diff --git a/app/modules/web/Controllers/AccountFileController.php b/app/modules/web/Controllers/AccountFileController.php
index 8c65f5a9..1a358f10 100644
--- a/app/modules/web/Controllers/AccountFileController.php
+++ b/app/modules/web/Controllers/AccountFileController.php
@@ -153,21 +153,23 @@ final class AccountFileController extends ControllerBase implements CrudControll
);
$response = $this->router->response();
- $response->header('Cache-Control', 'max-age=60, must-revalidate');
- $response->header('Content-length', $fileData->getSize());
- $response->header('Content-type', $fileData->getType());
+ $response->header('Content-Length', $fileData->getSize());
+ $response->header('Content-Type', $fileData->getType());
$response->header('Content-Description', ' sysPass file');
- $response->header('Content-transfer-encoding', 'binary');
+ $response->header('Content-Transfer-Encoding', 'binary');
+ $response->header('Accept-Ranges', 'bytes');
$type = strtolower($fileData->getType());
if ($type === 'application/pdf') {
- $response->header('Content-Disposition', 'inline; filename="' . $fileData->getName() . '"');
+ $disposition = sprintf('inline; filename="%s"', $fileData->getName());
} else {
+ $disposition = sprintf('attachment; filename="%s"', $fileData->getName());
$response->header('Set-Cookie', 'fileDownload=true; path=/');
- $response->header('Content-Disposition', 'attachment; filename="' . $fileData->getName() . '"');
}
+ $response->header('Content-Disposition', $disposition);
+
$response->body($fileData->getContent());
$response->send(true);
} catch (Exception $e) {
diff --git a/app/modules/web/themes/material-blue/views/account/search-rows.inc b/app/modules/web/themes/material-blue/views/account/search-rows.inc
index 4ca8707d..7bfe1cab 100644
--- a/app/modules/web/themes/material-blue/views/account/search-rows.inc
+++ b/app/modules/web/themes/material-blue/views/account/search-rows.inc
@@ -180,7 +180,7 @@ $favoriteRouteOff = $_getvar('favoriteRouteOff');
- getShortNotes(), ENT_QUOTES); ?>
+ getShortNotes(); ?>
diff --git a/lib/SP/Services/Account/AccountCryptService.php b/lib/SP/Services/Account/AccountCryptService.php
index 49868073..ceb4732f 100644
--- a/lib/SP/Services/Account/AccountCryptService.php
+++ b/lib/SP/Services/Account/AccountCryptService.php
@@ -70,23 +70,34 @@ final class AccountCryptService extends Service
$this->request = $updateMasterPassRequest;
try {
- $this->eventDispatcher->notifyEvent('update.masterPassword.accounts.start',
- new Event($this, EventMessage::factory()->addDescription(__u('Update Master Password')))
+ $this->eventDispatcher->notifyEvent(
+ 'update.masterPassword.accounts.start',
+ new Event($this,
+ EventMessage::factory()
+ ->addDescription(__u('Update Master Password'))
+ )
);
if ($this->request->useTask()) {
$task = $this->request->getTask();
TaskFactory::update($task,
- TaskFactory::createMessage($task->getTaskId(), __u('Update Master Password'))
+ TaskFactory::createMessage($task->getTaskId(),
+ __u('Update Master Password'))
);
}
- $eventMessage = $this->processAccounts($this->accountService->getAccountsPassData(), function ($request) {
- $this->accountService->updatePasswordMasterPass($request);
- });
+ $eventMessage = $this->processAccounts(
+ $this->accountService->getAccountsPassData(),
+ function (AccountPasswordRequest $request) {
+ $this->accountService->updatePasswordMasterPass($request);
+ }
+ );
- $this->eventDispatcher->notifyEvent('update.masterPassword.accounts.end', new Event($this, $eventMessage));
+ $this->eventDispatcher->notifyEvent(
+ 'update.masterPassword.accounts.end',
+ new Event($this, $eventMessage)
+ );
} catch (Exception $e) {
$this->eventDispatcher->notifyEvent('exception', new Event($e));
@@ -104,7 +115,6 @@ final class AccountCryptService extends Service
* @param callable $passUpdater
*
* @return EventMessage
- * @throws ServiceException
*/
private function processAccounts(array $accounts, callable $passUpdater)
{
@@ -116,8 +126,14 @@ final class AccountCryptService extends Service
$startTime = time();
$numAccounts = count($accounts);
+ $eventMessage = EventMessage::factory();
+
if ($numAccounts === 0) {
- throw new ServiceException(__u('Error while retrieving the accounts\' passwords'), ServiceException::ERROR);
+ $eventMessage->addDescription(__u('There are no accounts for processing'));
+ $eventMessage->addDetail(__u('Accounts updated'), __u('N/A'));
+ $eventMessage->addDetail(__u('Errors'), 0);
+
+ return $eventMessage;
}
$configData = $this->config->getConfigData();
@@ -127,8 +143,6 @@ final class AccountCryptService extends Service
$task = $this->request->getTask();
}
- $eventMessage = EventMessage::factory();
-
foreach ($accounts as $account) {
// No realizar cambios si está en modo demo
if ($configData->isDemoEnabled()) {
@@ -140,8 +154,10 @@ final class AccountCryptService extends Service
$eta = Util::getETA($startTime, $counter, $numAccounts);
if (isset($task)) {
- $taskMessage = TaskFactory::createMessage($task->getTaskId(), __('Update Master Password'))
- ->setMessage(sprintf(__('Accounts updated: %d / %d'), $counter, $numAccounts))
+ $taskMessage = TaskFactory::createMessage(
+ $task->getTaskId(),
+ __('Update Master Password')
+ )->setMessage(sprintf(__('Accounts updated: %d / %d'), $counter, $numAccounts))
->setProgress(round(($counter * 100) / $numAccounts, 2))
->setTime(sprintf('ETA: %ds (%.2f/s)', $eta[0], $eta[1]));
@@ -213,26 +229,35 @@ final class AccountCryptService extends Service
$this->request = $updateMasterPassRequest;
try {
- $this->eventDispatcher->notifyEvent('update.masterPassword.accountsHistory.start',
- new Event($this, EventMessage::factory()->addDescription(__u('Update Master Password (H)')))
+ $this->eventDispatcher->notifyEvent(
+ 'update.masterPassword.accountsHistory.start',
+ new Event($this,
+ EventMessage::factory()
+ ->addDescription(__u('Update Master Password (H)'))
+ )
);
if ($this->request->useTask()) {
$task = $this->request->getTask();
TaskFactory::update($task,
- TaskFactory::createMessage($task->getTaskId(), __u('Update Master Password (H)'))
+ TaskFactory::createMessage($task->getTaskId(),
+ __u('Update Master Password (H)'))
);
}
- $eventMessage = $this->processAccounts($this->accountHistoryService->getAccountsPassData(), function ($request) {
- /** @var AccountPasswordRequest $request */
- $request->hash = $this->request->getHash();
+ $eventMessage = $this->processAccounts(
+ $this->accountHistoryService->getAccountsPassData(),
+ function (AccountPasswordRequest $request) {
+ $request->hash = $this->request->getHash();
- $this->accountHistoryService->updatePasswordMasterPass($request);
- });
+ $this->accountHistoryService->updatePasswordMasterPass($request);
+ });
- $this->eventDispatcher->notifyEvent('update.masterPassword.accountsHistory.end', new Event($this, $eventMessage));
+ $this->eventDispatcher->notifyEvent(
+ 'update.masterPassword.accountsHistory.end',
+ new Event($this, $eventMessage)
+ );
} catch (Exception $e) {
$this->eventDispatcher->notifyEvent('exception', new Event($e));
diff --git a/lib/SP/Services/Account/AccountSearchItem.php b/lib/SP/Services/Account/AccountSearchItem.php
index d6491b70..674bd71e 100644
--- a/lib/SP/Services/Account/AccountSearchItem.php
+++ b/lib/SP/Services/Account/AccountSearchItem.php
@@ -379,7 +379,7 @@ final class AccountSearchItem
public function getShortNotes()
{
if ($this->accountSearchVData->getNotes()) {
- return nl2br(Html::truncate($this->accountSearchVData->getNotes(), 300));
+ return nl2br(htmlspecialchars(Html::truncate($this->accountSearchVData->getNotes(), 300), ENT_QUOTES));
}
return '';
diff --git a/lib/SP/Services/Api/ApiService.php b/lib/SP/Services/Api/ApiService.php
index 03fd67f9..81e45ba1 100644
--- a/lib/SP/Services/Api/ApiService.php
+++ b/lib/SP/Services/Api/ApiService.php
@@ -33,6 +33,7 @@ use SP\Core\Exceptions\InvalidClassException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\AuthTokenData;
use SP\Modules\Api\Controllers\Help\HelpInterface;
+use SP\Repositories\NoSuchItemException;
use SP\Repositories\Track\TrackRequest;
use SP\Services\AuthToken\AuthTokenService;
use SP\Services\Service;
@@ -103,7 +104,19 @@ final class ApiService extends Service
);
}
- $this->authTokenData = $this->authTokenService->getTokenByToken($actionId, $this->getParam('authToken'));
+ try {
+ $this->authTokenData = $this->authTokenService->getTokenByToken($actionId, $this->getParam('authToken'));
+ } catch (NoSuchItemException $e) {
+ logger($e->getMessage(), 'ERROR');
+
+ // For security reasons there won't be any hint about a not found token...
+ throw new ServiceException(
+ __u('Internal error'),
+ ServiceException::ERROR,
+ null,
+ JsonRpcResponse::INTERNAL_ERROR
+ );
+ }
if ($this->authTokenData->getActionId() !== $actionId) {
$this->accessDenied();
diff --git a/lib/SP/Services/AuthToken/AuthTokenService.php b/lib/SP/Services/AuthToken/AuthTokenService.php
index 78a24a17..729e1472 100644
--- a/lib/SP/Services/AuthToken/AuthTokenService.php
+++ b/lib/SP/Services/AuthToken/AuthTokenService.php
@@ -307,15 +307,15 @@ final class AuthTokenService extends Service
*
* @return false|AuthTokenData
* @throws ConstraintException
+ * @throws NoSuchItemException
* @throws QueryException
- * @throws ServiceException
*/
public function getTokenByToken($actionId, $token)
{
$result = $this->authTokenRepository->getTokenByToken($actionId, $token);
if ($result->getNumRows() === 0) {
- throw new ServiceException(__u('Internal error'));
+ throw new NoSuchItemException(__u('Token not found'));
}
return $result->getData();
diff --git a/lib/SP/Services/Install/Installer.php b/lib/SP/Services/Install/Installer.php
index c27dfb94..7da4009e 100644
--- a/lib/SP/Services/Install/Installer.php
+++ b/lib/SP/Services/Install/Installer.php
@@ -60,9 +60,9 @@ final class Installer extends Service
/**
* sysPass' version and build number
*/
- const VERSION = [3, 1, 0];
+ const VERSION = [3, 1, 1];
const VERSION_TEXT = '3.1';
- const BUILD = 19081801;
+ const BUILD = 19121601;
/**
* @var DatabaseSetupInterface
diff --git a/public/js/app-actions.js b/public/js/app-actions.js
index 54d6cad0..566e3ab9 100644
--- a/public/js/app-actions.js
+++ b/public/js/app-actions.js
@@ -948,11 +948,15 @@ sysPass.Actions = function (log) {
sk: sysPassApp.sk.get()
}));
- if (fileType === 'application/pdf') {
+ if (fileType.toUpperCase() === 'PDF') {
+ log.info("Opening PDF file in new window/tab");
+
window.open(url, '_blank');
return;
}
+ log.info("Downloading file");
+
$.fileDownload(url,
{
httpMethod: "GET",
diff --git a/public/js/app-actions.min.js b/public/js/app-actions.min.js
index 2e874404..6aa453fa 100644
--- a/public/js/app-actions.min.js
+++ b/public/js/app-actions.min.js
@@ -34,27 +34,27 @@ sysPassApp.sk.set(a.csrf)})},nav:function(a,b){c.info("grid:nav");var d=$("#"+a.
sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(a){a.preventDefault();"function"===typeof b&&b(c)}}})},getSelection:function(a){a=a.data("selection");var b=[];return a&&($(a).find(".is-selected").each(function(){b.push($(this).data("item-id"))}),0===b.length)?!1:b}},r={runner:null,run:function(a){c.info("task:run");c.info("taskId: "+a);var b=$("#taskStatus");b.css("display","block");b.empty().html(sysPassApp.config.LANG[62]);var d=sysPassApp.requests.getRequestOpts();
d.method="get";d.url=sysPassApp.util.getUrl(e.entrypoint,{r:["task/trackStatus",a]});return this.runner=sysPassApp.requests.getActionEvent(d,function(a){a=a.task+" - "+a.message+" - "+a.time+" - "+a.progress+"%
"+sysPassApp.config.LANG[62];c.info(a);b.empty().html(a)})},end:function(){c.info("task:end");null!==this.runner&&(c.info("Task ended"),this.runner.close(),$("#taskStatus").css("display","none"))}};return{getContent:f,showFloatingBox:h,closeFloatingBox:p,appMgmt:v,account:m,accountManager:{restore:function(a){c.info("accountManager:restore");
g.state.update(a);var b=a.data("item-id"),d=sysPassApp.requests.getRequestOpts();d.method="get";d.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(d,function(d){sysPassApp.msg.out(d);0===d.status&&((d=a.data("action-next"))?f({r:[d,b]}):f({r:g.state.tab.route,tabIndex:g.state.tab.index}))})}},file:{view:function(a){c.info("file:view");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=
-sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(b,function(b){if(0!==b.status)return sysPassApp.msg.out(b);q(a,b.data.html)})},download:function(a){c.info("file:download");var b=a.data("item-type");a=sysPassApp.requests.getUrl(sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()}));"application/pdf"===b?window.open(a,"_blank"):$.fileDownload(a,{httpMethod:"GET",
-successCallback:function(a){sysPassApp.msg.ok(sysPassApp.config.LANG[72])}})},delete:function(a){c.info("file:delete");var b=''+sysPassApp.config.LANG[15]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,
-{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&m.listFiles($("#list-account-files"))})}}})}},checks:{wiki:function(a){c.info("checks:wiki");a=$(a.data("src"));a.find("[name='sk']").val(sysPassApp.sk.get());var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&$("#dokuWikiResCheck").html(a.data)})}},
-config:{save:function(a){c.info("config:save");g.save(a)},masterpass:function(a){c.info("config:masterpass");var b=''+sysPassApp.config.LANG[59]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(b){b.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44]);a.find(":input[type=password]").val("")}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=a.find("input[name='taskId']").val();var d=sysPassApp.requests.getRequestOpts();
-b&&(d.useFullLoading=!0,r.run(b));d.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route")});d.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(b){sysPassApp.msg.out(b);a.find(":input[type=password]").val("");r.end()})}}})},backup:function(a){c.info("config:backup");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("action-route");b.useFullLoading=!0;b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,
-function(a){sysPassApp.msg.out(a);0===a.status&&f({r:g.state.tab.route,tabIndex:g.state.tab.index})})},export:function(a){c.info("config:export");g.save(a)},import:function(a){c.info("config:import");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("action-route");b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a)})},refreshMpass:function(a){c.info("config:import");var b=sysPassApp.requests.getRequestOpts();
-b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a)})},mailCheck:function(a){c.info("config:mailCheck");var b=$(a.data("src")),d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint+"?r="+a.data("action-route");d.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a)})}},main:w,user:{showSettings:function(a){c.info("user:showSettings");
-f({r:a.data("action-route")},"userSettings")},saveSettings:function(a){c.info("user:saveSettings");g.save(a)},password:function(a){c.info("user:password");var b=sysPassApp.requests.getRequestOpts();b.type="html";b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){0===a.length?w.logout():h(a)})},passreset:function(a){c.info("user:passreset");var b=sysPassApp.requests.getRequestOpts();
-b.url=e.entrypoint+"/?r="+a.data("action-route");b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})},savePassword:function(a){c.info("user:savepassword");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("action-route");b.method="post";b.data=a.serialize();b.data+="&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);
-0===a.status&&(p(),"function"===typeof onSuccess&&onSuccess())})}},link:{save:function(a){c.info("link:save");var b=function(b){var d=a.data("account-id"),c=sysPassApp.requests.getRequestOpts();c.method="get";d?c.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),d,b],sk:sysPassApp.sk.get(),isAjax:1}):(c.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),sk:sysPassApp.sk.get(),isAjax:1}),c.data=a.serialize());sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);
-0===b.status&&f({r:[a.data("action-next"),d]})})},d=''+sysPassApp.config.LANG[48]+"
";mdlDialog().show({text:d,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();b(0)}},positive:{title:sysPassApp.config.LANG[43],onClick:function(a){a.preventDefault();b(1)}}})},delete:function(a){c.info("link:delete");var b=''+sysPassApp.config.LANG[12]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],
-onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:[a.data("action-next"),a.data("account-id")]})})}}})},refresh:function(a){c.info("link:refresh");
-g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&((b=a.data("action-next"))?f({r:[b,a.data("account-id")]}):f({r:g.state.tab.route,tabIndex:g.state.tab.index}))})}},eventlog:{clear:function(a){var b=''+sysPassApp.config.LANG[20]+"
";
-mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})},refresh:function(a){$("#"+a.data("action-form")).submit()}},ajaxUrl:e,plugin:{toggle:function(a){c.info("plugin:enable");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),
-a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})},reset:function(a){c.info("plugin:reset");var b=''+sysPassApp.config.LANG[58]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],
-onClick:function(b){b.preventDefault();b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:a.data("action-next")})})}}})},search:function(a){c.info("plugin:search");l.search(a)},show:function(a){c.info("plugin:show");v.show(a)},save:function(a){c.info("plugin:save");var b=sysPassApp.requests.getRequestOpts();
-b.url=e.entrypoint+"?r="+a.data("route");b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&(f({r:a.data("action-next")}),$.magnificPopup.close())})},nav:function(a){c.info("plugin:nav");l.nav(a)},delete:function(a){c.info("plugin:delete");l.delete(a,function(b){var d=sysPassApp.requests.getRequestOpts();d.method="get";d.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),0===b.length?a.data("item-id"):
-null],sk:sysPassApp.sk.get(),isAjax:1});d.data={items:b};sysPassApp.requests.getActionCall(d,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:a.data("action-next")})})})}},notification:t,wiki:{show:function(a){c.info("wiki:show");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),pageName:a.data("pagename"),actionId:a.data("action-id"),sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){0!==
-a.status?sysPassApp.msg.out(a):h(a.data.html)})}},items:{get:function(a){c.info("items:get");var b=a[0].selectize;b.clearOptions();b.load(function(d){var c=sysPassApp.requests.getRequestOpts();c.method="get";c.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(c,function(c){d(c.data);b.setValue(a.data("selected-id"),!0);sysPassApp.triggers.updateFormHash()})})},update:function(a){c.info("items:update");var b=
-$("#"+a.data("item-dst"))[0].selectize,d=b.getValue();b.clearOptions();b.load(function(c){var f=sysPassApp.requests.getRequestOpts();f.method="get";f.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("item-route"),sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(f,function(a){c(a);b.setValue(d,!0)})})}},ldap:{check:function(a){c.info("ldap:check");var b=$(a.data("src")),d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint+"?r="+a.data("action-route");d.data=b.serialize()+"&sk="+sysPassApp.sk.get();
-sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a);0===a.status&&void 0!==a.data.template&&void 0!==a.data.items&&h(a.data.template,{open:function(){var b=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){b.append(sysPassApp.theme.html.getList(a.items,a.icon))})}})})},import:function(a){c.info("ldap:import");var b=''+sysPassApp.config.LANG[57]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],
-onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=$(a.data("src"));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint+"?r="+a.data("action-route");c.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a)})}}})}},track:{unlock:function(a){c.info("track:unlock");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=
-sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);g.refresh(a)})},clear:function(a){c.info("track:clear");var b=''+sysPassApp.config.LANG[71]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],
-onClick:function(b){b.preventDefault();g.save(a)}}})},refresh:function(a){$("#"+a.data("action-form")).submit()}}}};
+sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(b,function(b){if(0!==b.status)return sysPassApp.msg.out(b);q(a,b.data.html)})},download:function(a){c.info("file:download");var b=a.data("item-type");a=sysPassApp.requests.getUrl(sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()}));"PDF"===b.toUpperCase()?(c.info("Opening PDF file in new window/tab"),window.open(a,
+"_blank")):(c.info("Downloading file"),$.fileDownload(a,{httpMethod:"GET",successCallback:function(a){sysPassApp.msg.ok(sysPassApp.config.LANG[72])}}))},delete:function(a){c.info("file:delete");var b=''+sysPassApp.config.LANG[15]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=
+sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&m.listFiles($("#list-account-files"))})}}})}},checks:{wiki:function(a){c.info("checks:wiki");a=$(a.data("src"));a.find("[name='sk']").val(sysPassApp.sk.get());var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint;b.data=a.serialize();sysPassApp.requests.getActionCall(b,
+function(a){sysPassApp.msg.out(a);0===a.status&&$("#dokuWikiResCheck").html(a.data)})}},config:{save:function(a){c.info("config:save");g.save(a)},masterpass:function(a){c.info("config:masterpass");var b=''+sysPassApp.config.LANG[59]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(b){b.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44]);a.find(":input[type=password]").val("")}},positive:{title:sysPassApp.config.LANG[43],
+onClick:function(b){b=a.find("input[name='taskId']").val();var d=sysPassApp.requests.getRequestOpts();b&&(d.useFullLoading=!0,r.run(b));d.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route")});d.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(b){sysPassApp.msg.out(b);a.find(":input[type=password]").val("");r.end()})}}})},backup:function(a){c.info("config:backup");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+
+"?r="+a.data("action-route");b.useFullLoading=!0;b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&f({r:g.state.tab.route,tabIndex:g.state.tab.index})})},export:function(a){c.info("config:export");g.save(a)},import:function(a){c.info("config:import");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("action-route");b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,
+function(a){sysPassApp.msg.out(a)})},refreshMpass:function(a){c.info("config:import");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("action-route"),sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a)})},mailCheck:function(a){c.info("config:mailCheck");var b=$(a.data("src")),d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint+"?r="+a.data("action-route");d.data=b.serialize()+"&sk="+
+sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a)})}},main:w,user:{showSettings:function(a){c.info("user:showSettings");f({r:a.data("action-route")},"userSettings")},saveSettings:function(a){c.info("user:saveSettings");g.save(a)},password:function(a){c.info("user:password");var b=sysPassApp.requests.getRequestOpts();b.type="html";b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});
+sysPassApp.requests.getActionCall(b,function(a){0===a.length?w.logout():h(a)})},passreset:function(a){c.info("user:passreset");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"/?r="+a.data("action-route");b.data=a.serialize();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})},savePassword:function(a){c.info("user:savepassword");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+
+"?r="+a.data("action-route");b.method="post";b.data=a.serialize();b.data+="&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&(p(),"function"===typeof onSuccess&&onSuccess())})}},link:{save:function(a){c.info("link:save");var b=function(b){var d=a.data("account-id"),c=sysPassApp.requests.getRequestOpts();c.method="get";d?c.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),d,b],sk:sysPassApp.sk.get(),isAjax:1}):(c.url=sysPassApp.util.getUrl(e.entrypoint,
+{r:a.data("action-route"),sk:sysPassApp.sk.get(),isAjax:1}),c.data=a.serialize());sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:[a.data("action-next"),d]})})},d=''+sysPassApp.config.LANG[48]+"
";mdlDialog().show({text:d,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();b(0)}},positive:{title:sysPassApp.config.LANG[43],onClick:function(a){a.preventDefault();b(1)}}})},delete:function(a){c.info("link:delete");
+var b=''+sysPassApp.config.LANG[12]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,
+function(b){sysPassApp.msg.out(b);0===b.status&&f({r:[a.data("action-next"),a.data("account-id")]})})}}})},refresh:function(a){c.info("link:refresh");g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&((b=a.data("action-next"))?f({r:[b,a.data("account-id")]}):f({r:g.state.tab.route,
+tabIndex:g.state.tab.index}))})}},eventlog:{clear:function(a){var b=''+sysPassApp.config.LANG[20]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})},refresh:function(a){$("#"+a.data("action-form")).submit()}},ajaxUrl:e,plugin:{toggle:function(a){c.info("plugin:enable");
+g.state.update(a);var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){sysPassApp.msg.out(a);0===a.status&&setTimeout(function(){sysPassApp.util.redirect("index.php")},2E3)})},reset:function(a){c.info("plugin:reset");var b=''+sysPassApp.config.LANG[58]+"
";mdlDialog().show({text:b,
+negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:a.data("action-next")})})}}})},
+search:function(a){c.info("plugin:search");l.search(a)},show:function(a){c.info("plugin:show");v.show(a)},save:function(a){c.info("plugin:save");var b=sysPassApp.requests.getRequestOpts();b.url=e.entrypoint+"?r="+a.data("route");b.data=a.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);0===b.status&&(f({r:a.data("action-next")}),$.magnificPopup.close())})},nav:function(a){c.info("plugin:nav");l.nav(a)},delete:function(a){c.info("plugin:delete");
+l.delete(a,function(b){var d=sysPassApp.requests.getRequestOpts();d.method="get";d.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),0===b.length?a.data("item-id"):null],sk:sysPassApp.sk.get(),isAjax:1});d.data={items:b};sysPassApp.requests.getActionCall(d,function(b){sysPassApp.msg.out(b);0===b.status&&f({r:a.data("action-next")})})})}},notification:t,wiki:{show:function(a){c.info("wiki:show");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,
+{r:a.data("action-route"),pageName:a.data("pagename"),actionId:a.data("action-id"),sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(a){0!==a.status?sysPassApp.msg.out(a):h(a.data.html)})}},items:{get:function(a){c.info("items:get");var b=a[0].selectize;b.clearOptions();b.load(function(d){var c=sysPassApp.requests.getRequestOpts();c.method="get";c.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(c,
+function(c){d(c.data);b.setValue(a.data("selected-id"),!0);sysPassApp.triggers.updateFormHash()})})},update:function(a){c.info("items:update");var b=$("#"+a.data("item-dst"))[0].selectize,d=b.getValue();b.clearOptions();b.load(function(c){var f=sysPassApp.requests.getRequestOpts();f.method="get";f.url=sysPassApp.util.getUrl(e.entrypoint,{r:a.data("item-route"),sk:sysPassApp.sk.get()});sysPassApp.requests.getActionCall(f,function(a){c(a);b.setValue(d,!0)})})}},ldap:{check:function(a){c.info("ldap:check");
+var b=$(a.data("src")),d=sysPassApp.requests.getRequestOpts();d.url=e.entrypoint+"?r="+a.data("action-route");d.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a);0===a.status&&void 0!==a.data.template&&void 0!==a.data.items&&h(a.data.template,{open:function(){var b=$("#ldap-results").find(".list-wrap").empty();a.data.items.forEach(function(a){b.append(sysPassApp.theme.html.getList(a.items,a.icon))})}})})},import:function(a){c.info("ldap:import");
+var b=''+sysPassApp.config.LANG[57]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b=$(a.data("src"));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint+"?r="+a.data("action-route");c.data=b.serialize()+"&sk="+sysPassApp.sk.get();sysPassApp.requests.getActionCall(c,function(a){sysPassApp.msg.out(a)})}}})}},
+track:{unlock:function(a){c.info("track:unlock");var b=sysPassApp.requests.getRequestOpts();b.method="get";b.url=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(b,function(b){sysPassApp.msg.out(b);g.refresh(a)})},clear:function(a){c.info("track:clear");var b=''+sysPassApp.config.LANG[71]+"
";mdlDialog().show({text:b,negative:{title:sysPassApp.config.LANG[44],
+onClick:function(a){a.preventDefault();sysPassApp.msg.error(sysPassApp.config.LANG[44])}},positive:{title:sysPassApp.config.LANG[43],onClick:function(b){b.preventDefault();g.save(a)}}})},refresh:function(a){$("#"+a.data("action-form")).submit()}}}};
diff --git a/schemas/31019012201.sql b/schemas/31019012201.sql
index 1325330e..b0c68944 100644
--- a/schemas/31019012201.sql
+++ b/schemas/31019012201.sql
@@ -5,13 +5,13 @@ alter table Plugin
create table PluginData
(
- name varchar(100) not null,
- itemId int not null,
- `data` blob not null,
- `key` varbinary(2000) not null,
- constraint `PRIMARY`
+ name varchar(100) not null,
+ itemId int not null,
+ `data` blob not null,
+ `key` varbinary(2000) not null,
primary key (name, itemId),
- constraint fk_PluginData_name
- foreign key (name) references Plugin (name)
- on update cascade on delete cascade
-)$$
\ No newline at end of file
+ constraint fk_PluginData_name
+ foreign key (name) references Plugin (name)
+ on update cascade
+ on delete cascade
+) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE utf8_unicode_ci $$
\ No newline at end of file