* [FIX] Fixed URL when downloading resources and sysPass id behind a reverse proxy. Thanks to @vmario89 for the feedback. Closes #1102

* [FIX] Fixed wrong behavior when copying to clipboard an account's password through public link
* [MOD] Improved URL handling
* [MOD] Improved deep links handling

Signed-off-by: nuxsmin <nuxsmin@syspass.org>
This commit is contained in:
nuxsmin
2018-11-17 13:11:58 +01:00
parent 6070d94f39
commit 98fe0ba35c
15 changed files with 138 additions and 85 deletions

View File

@@ -136,6 +136,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
try {
$this->checkSecurityToken($this->previousSk, $this->request);
$this->view->addTemplate('account');
$accountDetailsResponse = $this->accountService->getById($id);
$this->accountService
->withUsersById($accountDetailsResponse)
@@ -146,7 +148,6 @@ final class AccountController extends ControllerBase implements CrudControllerIn
$accountHelper->setIsView(true);
$accountHelper->setViewForAccount($accountDetailsResponse, Acl::ACCOUNT_VIEW);
$this->view->addTemplate('account');
$this->view->assign('title',
[
'class' => 'titleNormal',
@@ -169,6 +170,12 @@ final class AccountController extends ControllerBase implements CrudControllerIn
$this->eventDispatcher->notifyEvent('exception', new Event($e));
if ($this->isAjax === false
&& !$this->view->isUpgraded()
) {
$this->upgradeView();
}
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -282,6 +289,12 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
if ($this->isAjax === false
&& !$this->view->isUpgraded()
) {
$this->upgradeView();
}
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -330,6 +343,12 @@ final class AccountController extends ControllerBase implements CrudControllerIn
$this->eventDispatcher->notifyEvent('exception', new Event($e));
if ($this->isAjax === false
&& !$this->view->isUpgraded()
) {
$this->upgradeView();
}
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -380,6 +399,12 @@ final class AccountController extends ControllerBase implements CrudControllerIn
$this->eventDispatcher->notifyEvent('exception', new Event($e));
if ($this->isAjax === false
&& !$this->view->isUpgraded()
) {
$this->upgradeView();
}
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -427,6 +452,12 @@ final class AccountController extends ControllerBase implements CrudControllerIn
$this->eventDispatcher->notifyEvent('exception', new Event($e));
if ($this->isAjax === false
&& !$this->view->isUpgraded()
) {
$this->upgradeView();
}
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -474,6 +505,12 @@ final class AccountController extends ControllerBase implements CrudControllerIn
$this->eventDispatcher->notifyEvent('exception', new Event($e));
if ($this->isAjax === false
&& !$this->view->isUpgraded()
) {
$this->upgradeView();
}
ErrorUtil::showExceptionInView($this->view, $e, 'account-editpass');
}
}
@@ -521,6 +558,12 @@ final class AccountController extends ControllerBase implements CrudControllerIn
$this->eventDispatcher->notifyEvent('exception', new Event($e));
if ($this->isAjax === false
&& !$this->view->isUpgraded()
) {
$this->upgradeView();
}
ErrorUtil::showExceptionInView($this->view, $e, 'account-history');
}
}
@@ -557,6 +600,12 @@ final class AccountController extends ControllerBase implements CrudControllerIn
$this->eventDispatcher->notifyEvent('exception', new Event($e));
if ($this->isAjax === false
&& !$this->view->isUpgraded()
) {
$this->upgradeView();
}
ErrorUtil::showExceptionInView($this->view, $e, 'account-request');
}
}

View File

@@ -24,6 +24,7 @@
namespace SP\Modules\Web\Controllers\Helpers\Account;
use SP\Bootstrap;
use SP\Core\Acl\AccountPermissionException;
use SP\Core\Acl\Acl;
use SP\Core\Acl\ActionsInterface;
@@ -322,7 +323,7 @@ final class AccountHelper extends HelperBase
{
$route = Acl::getActionRoute($this->actionId) . ($this->accountId ? '/' . $this->accountId : '');
$uri = new Uri('index.php');
$uri = new Uri(Bootstrap::$WEBROOT . Bootstrap::$SUBURI);
$uri->addParam('r', $route);
return $uri->getUriSigned($this->configData->getPasswordSalt());

View File

@@ -102,10 +102,10 @@ final class LayoutHelper extends HelperBase
$this->view->assign('app_website_url', AppInfoInterface::APP_WEBSITE_URL);
$this->view->assign('app_blog_url', AppInfoInterface::APP_BLOG_URL);
$this->view->assign('app_version', Installer::VERSION_TEXT);
$this->view->assign('logoIcon', Bootstrap::$WEBURI . '/public/images/logo_icon.png');
$this->view->assign('logoNoText', Bootstrap::$WEBURI . '/public/images/logo_icon.svg');
$this->view->assign('logo', Bootstrap::$WEBURI . '/public/images/logo_full_bg.png');
$this->view->assign('logonobg', Bootstrap::$WEBURI . '/public/images/logo_full_nobg.png');
$this->view->assign('logoIcon', Bootstrap::$WEBROOT . '/public/images/logo_icon.png');
$this->view->assign('logoNoText', Bootstrap::$WEBROOT . '/public/images/logo_icon.svg');
$this->view->assign('logo', Bootstrap::$WEBROOT . '/public/images/logo_full_bg.png');
$this->view->assign('logonobg', Bootstrap::$WEBROOT . '/public/images/logo_full_nobg.png');
$this->view->assign('httpsEnabled', $this->request->isHttps());
$this->view->assign('homeRoute', Acl::getActionRoute(ActionsInterface::ACCOUNT));
@@ -134,8 +134,9 @@ final class LayoutHelper extends HelperBase
protected function getResourcesLinks()
{
$version = VersionUtil::getVersionStringNormalized();
$uri = Bootstrap::$WEBROOT . Bootstrap::$SUBURI;
$jsUri = new Uri(Bootstrap::$WEBURI . '/index.php');
$jsUri = new Uri($uri);
$jsUri->addParam('_r', 'resource/js');
$jsUri->addParam('_v', md5($version));
@@ -164,7 +165,7 @@ final class LayoutHelper extends HelperBase
$resultsAsCards = $this->configData->isResultsAsCards();
}
$cssUri = new Uri(Bootstrap::$WEBURI . '/index.php');
$cssUri = new Uri($uri);
$cssUri->addParam('_r', 'resource/css');
$cssUri->addParam('_v', md5($version . $resultsAsCards));

View File

@@ -24,6 +24,7 @@
namespace SP\Modules\Web\Controllers;
use SP\Bootstrap;
use SP\Core\Context\SessionContext;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
@@ -63,7 +64,7 @@ final class LoginController extends ControllerBase
$this->checkForwarded();
$redirector = function ($route) use ($from) {
$uri = new Uri('index.php');
$uri = new Uri(Bootstrap::$SUBURI);
$uri->addParam('r', $route);
if ($from !== null) {

View File

@@ -79,7 +79,7 @@ trait JsonTrait
$jsonResponse->setStatus($status);
$jsonResponse->setData($data);
if (property_exists($this, 'session')) {
if (isset($this->session)) {
$jsonResponse->setCsrf($this->session->getSecurityKey());
}
@@ -112,7 +112,7 @@ trait JsonTrait
$jsonResponse->setMessages([$exception->getHint()]);
}
if (property_exists($this, 'session')) {
if (isset($this->session)) {
$jsonResponse->setCsrf($this->session->getSecurityKey());
}

View File

@@ -3,6 +3,7 @@
* @var \SP\Core\UI\ThemeIcons $icons
* @var \SP\Config\ConfigData $configData
* @var callable $_getvar
* @var callable $_getRoute
* @var \SP\Mvc\View\Template $this
*/
?>

View File

@@ -356,30 +356,14 @@ final class Bootstrap
*/
private function initPaths()
{
self::$SUBURI = str_replace("\\", '/', substr(realpath($this->request->getServer('SCRIPT_FILENAME')), strlen(APP_ROOT)));
self::$SUBURI = '/' . basename($this->request->getServer('SCRIPT_FILENAME'));
$scriptName = $this->request->getServer('REQUEST_URI');
$uri = $this->request->getServer('REQUEST_URI');
if (substr($scriptName, -1) === '/') {
$scriptName .= 'index.php';
$pos = strpos($uri, self::$SUBURI);
// Asegurar que suburi sigue las mismas reglas que scriptName
if (substr(self::$SUBURI, -9) !== 'index.php') {
if (substr(self::$SUBURI, -1) !== '/') {
self::$SUBURI .= '/';
}
self::$SUBURI .= 'index.php';
}
}
if (($pos = strpos($scriptName, self::$SUBURI)) === false) {
$pos = strpos($scriptName, '?');
}
self::$WEBROOT = substr($scriptName, 0, $pos);
if (self::$WEBROOT !== '' && self::$WEBROOT[0] !== '/') {
self::$WEBROOT = '/' . self::$WEBROOT;
if ($pos > 0) {
self::$WEBROOT = substr($uri, 0, $pos);
}
self::$WEBURI = $this->request->getHttpHost() . self::$WEBROOT;

View File

@@ -390,7 +390,12 @@ final class Request
}
if ($result === false) {
throw new SPException('URI string altered');
throw new SPException(
'URI string altered',
SPException::ERROR,
null,
1
);
}
}
@@ -416,12 +421,14 @@ final class Request
return strtolower($xForward['proto'] . '://' . $xForward['host']);
}
$protocol = 'http://';
// We got called directly
if ($this->https) {
return 'https://' . $this->request->server()->get('HTTP_HOST');
$protocol = 'https://';
}
return 'http://' . $this->request->server()->get('HTTP_HOST');
return $protocol . $this->request->server()->get('HTTP_HOST');
}
/**

View File

@@ -24,6 +24,7 @@
namespace SP\Mvc\Controller;
use SP\Bootstrap;
use SP\Config\ConfigData;
use SP\Core\Context\SessionContext;
use SP\Core\Exceptions\SPException;
@@ -38,6 +39,7 @@ use SP\Util\Util;
* Trait ControllerTrait
*
* @package SP\Mvc\Controller
* @property ConfigData $configData
*/
trait ControllerTrait
{
@@ -84,7 +86,7 @@ trait ControllerTrait
$route = $request->analyzeString('r');
$hash = $request->analyzeString('h');
$uri = new Uri('index.php');
$uri = new Uri(Bootstrap::$WEBROOT . Bootstrap::$SUBURI);
$uri->addParam('_r', 'login');
if ($route && $hash) {
@@ -112,10 +114,22 @@ trait ControllerTrait
*/
protected function checkSecurityToken($previousToken, Request $request)
{
$sk = $request->analyzeString('sk');
if ($request->analyzeString('h') !== null
&& $request->analyzeString('from') === null
&& isset($this->configData)
) {
$request->verifySignature($this->configData->getPasswordSalt());
} else {
$sk = $request->analyzeString('sk');
if (!$sk || $previousToken !== $sk) {
throw new SPException(__u('Invalid Action'));
if (!$sk || $previousToken !== $sk) {
throw new SPException(
__u('Invalid Action'),
SPException::ERROR,
null,
1
);
}
}
}

View File

@@ -29,6 +29,7 @@ defined('APP_ROOT') || die();
use SP\Bootstrap;
use SP\Core\Exceptions\FileNotFoundException;
use SP\Core\UI\ThemeInterface;
use SP\Http\Uri;
/**
* Class Template
@@ -371,7 +372,11 @@ final class Template
};
$_getRoute = function ($path) use ($sk) {
return Bootstrap::$WEBURI . '/index.php?r=' . $path . '&sk=' . $sk;
$uri = new Uri(Bootstrap::$WEBROOT . Bootstrap::$SUBURI);
$uri->addParam('r', $path);
$uri->addParam('sk', $sk);
return $uri->getUri();
};
ob_start();

View File

@@ -173,7 +173,9 @@ final class LoginService extends Service
$this->loadUserPreferences();
$this->cleanUserData();
return new LoginResponse(self::STATUS_PASS, 'index.php?r=' . ($this->from ?: 'index'));
$redirect = 'index.php?r=' . ($this->from ? $this->from . '&sk=' . $this->context->getSecurityKey() : 'index');
return new LoginResponse(self::STATUS_PASS, $redirect);
}
/**

View File

@@ -128,7 +128,7 @@ sysPass.Main = function () {
}
$("body").on("click", ".clip-pass-button", function () {
const json = sysPassApp.actions.account.copyPass($(this)).done(function (json) {
const json = oPublic.actions.account.copyPass($(this)).done(function (json) {
if (json.status !== 0) {
msg.out(json);
@@ -165,8 +165,10 @@ sysPass.Main = function () {
}
);
}).on("click", ".clip-pass-icon", function () {
const $target =$(this.dataset.clipboardTarget);
clipboard
.copy(sysPass.Util.decodeEntities($(this.dataset.clipboardTarget).val()))
.copy(oPublic.util.decodeEntities($target.val()))
.then(
function () {
msg.ok(oPublic.config.LANG[45]);
@@ -176,8 +178,10 @@ sysPass.Main = function () {
}
);
}).on("click", ".clip-pass-field", function () {
const target = document.getElementById(this.dataset.clipboardTarget);
clipboard
.copy(sysPass.Util.decodeEntities(document.getElementById(this.dataset.clipboardTarget).dataset.pass))
.copy(oPublic.util.decodeEntities(target.dataset.pass))
.then(
function () {
msg.ok(oPublic.config.LANG[45]);
@@ -364,7 +368,7 @@ sysPass.Main = function () {
this.warn(description);
break;
case 10:
sysPassApp.actions.main.logout();
oPublic.actions.main.logout();
break;
case 100:
this.ok(description);

View File

@@ -1,13 +1,13 @@
sysPass.Main=function(){var k=function(){d.info("checkPluginUpdates");for(var a in b.plugins)"function"===typeof b.plugins[a].checkVersion&&b.plugins[a].checkVersion().then(function(a){0===a.status&&void 0!==a.data.plugin&&e.info(String.format(b.config.LANG[67],a.data.plugin,a.data.remoteVersion))})},l=function(){d.info("bindPassEncrypt");$("body").on("blur",":input[type=password]",function(a){a=$(this);if(!a.hasClass("passwordfield__no-pki"))try{g(a)}catch(c){d.error(c),e.error(c)}}).on("keypress",
":input[type=password]",function(a){if(13===a.keyCode){a.preventDefault();a=$(this);try{g(a)}catch(c){d.error(c),e.error(c)}a.closest("form").submit()}})},m=function(){d.info("initializeClipboard");if(clipboard.isSupported())$("body").on("click",".clip-pass-button",function(){var a=sysPassApp.actions.account.copyPass($(this)).done(function(a){if(0!==a.status)return e.out(a),!1;h.set(a.csrf)});!1!==a&&clipboard.copy(a.responseJSON.data.accpass).then(function(){e.ok(b.config.LANG[45])},function(a){e.error(b.config.LANG[46])})}).on("click",
".dialog-clip-button",function(){var a=$(this.dataset.clipboardTarget);clipboard.copy(a.text().replace(/\r?\n|\r/g)).then(function(){$(".dialog-text").removeClass("dialog-clip-copy");a.addClass("dialog-clip-copy")},function(a){e.error(b.config.LANG[46])})}).on("click",".clip-pass-icon",function(){clipboard.copy(sysPass.Util.decodeEntities($(this.dataset.clipboardTarget).val())).then(function(){e.ok(b.config.LANG[45])},function(a){e.error(b.config.LANG[46])})}).on("click",".clip-pass-field",function(){clipboard.copy(sysPass.Util.decodeEntities(document.getElementById(this.dataset.clipboardTarget).dataset.pass)).then(function(){e.ok(b.config.LANG[45])},
function(a){e.error(b.config.LANG[46])})});else d.warn(b.config.LANG[65])},g=function(a){d.info("encryptFormValue");var c=a.val();if(""!==c&&parseInt(a.attr("data-length"))!==c.length){if(c.length>b.config.PKI.MAX_SIZE)throw a.val(""),"Data length too big for encrypting";c=b.config.PKI.CRYPTO.encrypt(c);a.val(c);a.attr("data-length",c.length)}},p=function(){d.info("checkLogout");return"login/logout"===n("r")?(e.sticky(b.config.LANG[61],function(){b.util.redirect("index.php?r=login")}),!0):!1},h={current:"",
get:function(){d.info("sk:get");return $("#container").attr("data-sk")},set:function(a){d.info("sk:set");d.debug(a);$("#container").attr("data-sk",a);this.current=a}},d={log:function(a){!0===b.config.DEBUG&&console.log(a)},info:function(a){!0===b.config.DEBUG&&console.info(a)},error:function(a){console.error(a)},warn:function(a){console.warn(a)},debug:function(a){!0===b.config.DEBUG&&console.debug(a)}};Object.freeze(d);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 q=function(){d.info("setupCallbacks");var a=$("#container"),c=a.data("page");if(0<c.length&&"function"===typeof b.triggers.views[c])b.triggers.views[c](a);0<$("footer").length&&b.triggers.views.footer();$("#btnBack").click(function(){b.util.redirect("index.php")});b.triggers.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,c){var f={timeOut:0};"function"===typeof c&&(f.onHidden=c);toastr.warning(a,b.config.LANG[60],f)},out:function(a){if("object"===typeof a){var c=a.status,b=a.description;void 0!==a.messages&&0<a.messages.length&&(b=b+"<br>"+a.messages.join("<br>"));switch(c){case 0:this.ok(b);break;case 1:this.error(b);break;case 2:this.warn(b);break;case 10:sysPassApp.actions.main.logout();break;
case 100:this.ok(b);this.sticky(b);break;case 101:this.error(b);this.sticky(b);break;case 102:this.warn(b);this.sticky(b);break;default:this.error(b)}}},html:{error:function(a){return'<p class="error round">Oops...<br>'+b.config.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 r=function(){d.info("getEnvironment");var a=window.location.pathname.split("/"),
c=sysPass.Config();c.setAppRoot(window.location.protocol+"//"+window.location.host+function(){for(var b="",c=1;c<=a.length-2;c++)b+="/"+a[c];return b}());var f=b.requests.getRequestOpts();f.url="/index.php?r=bootstrap/getEnvironment";f.method="get";f.useLoading=!1;f.data={isAjax:1};return b.requests.getActionCall(f,function(a){void 0!==a.data&&(c.setLang(a.data.lang),c.setSessionTimeout(a.data.session_timeout),c.setPkiKey(a.data.pki_key),c.setPkiSize(a.data.pki_max_size),c.setCheckUpdates(a.data.check_updates),
c.setCheckNotices(a.data.check_notices),c.setCheckNotifications(a.data.check_notifications),c.setTimezone(a.data.timezone),c.setLocale(a.data.locale),c.setDebugEnabled(a.data.debug),c.setFileMaxSize(a.data.max_file_size),c.setFileAccountAllowedMime(a.data.files_allowed_mime),c.setFileImportAllowedMime(a.data.import_allowed_mime),c.setCookiesEnabled(a.data.cookies_enabled),c.setPlugins(a.data.plugins),c.setLoggedIn(a.data.loggedin),c.setAuthBasicAutologinEnabled(a.data.authbasic_autologin),c.initialize(),
b.config=c.getConfig())}).fail(function(){e.error("Error while getting sysPass config<br/>Please try again or check web server logs")})},b={config:sysPass.Config().getConfig(),actions:sysPass.Actions(d),triggers:sysPass.Triggers(d),util:sysPass.Util(d),theme:{},plugins:{},sk:h,msg:e,log:d,encryptFormValue:g},n=function(a){for(var b=[],d,e=window.location.href.slice(window.location.href.indexOf("?")+1).split("&"),g=0;g<e.length;g++)d=e[g].split("="),b.push(d[0]),b[d[0]]=d[1];return void 0!==a&&void 0!==
b[a]?b[a]:b};return function(){d.info("init");"function"===typeof sysPass.Theme&&(b.theme=sysPass.Theme(d));b.requests=sysPass.Requests(b);r().then(function(){if(!p()&&(b.config.PKI.AVAILABLE&&l(),!1===b.config.BROWSER.COOKIES_ENABLED&&e.sticky(b.config.LANG[64]),m(),q(),0<b.config.PLUGINS.length)){d.info("initPlugins");for(var a={},c=0;c<b.config.PLUGINS.length;c++){var f=b.config.PLUGINS[c];"function"===typeof sysPass.Plugins[f]&&(a[f]=sysPass.Plugins[f](b))}b.plugins=a;!0===b.config.AUTH.LOGGEDIN&&
!0===b.config.STATUS.CHECK_UPDATES&&k()}Object.freeze(b)});return b}()};
sysPass.Main=function(){var k=function(){e.info("checkPluginUpdates");for(var a in b.plugins)"function"===typeof b.plugins[a].checkVersion&&b.plugins[a].checkVersion().then(function(a){0===a.status&&void 0!==a.data.plugin&&f.info(String.format(b.config.LANG[67],a.data.plugin,a.data.remoteVersion))})},l=function(){e.info("bindPassEncrypt");$("body").on("blur",":input[type=password]",function(a){a=$(this);if(!a.hasClass("passwordfield__no-pki"))try{g(a)}catch(c){e.error(c),f.error(c)}}).on("keypress",
":input[type=password]",function(a){if(13===a.keyCode){a.preventDefault();a=$(this);try{g(a)}catch(c){e.error(c),f.error(c)}a.closest("form").submit()}})},m=function(){e.info("initializeClipboard");if(clipboard.isSupported())$("body").on("click",".clip-pass-button",function(){var a=b.actions.account.copyPass($(this)).done(function(a){if(0!==a.status)return f.out(a),!1;h.set(a.csrf)});!1!==a&&clipboard.copy(a.responseJSON.data.accpass).then(function(){f.ok(b.config.LANG[45])},function(a){f.error(b.config.LANG[46])})}).on("click",
".dialog-clip-button",function(){var a=$(this.dataset.clipboardTarget);clipboard.copy(a.text().replace(/\r?\n|\r/g)).then(function(){$(".dialog-text").removeClass("dialog-clip-copy");a.addClass("dialog-clip-copy")},function(a){f.error(b.config.LANG[46])})}).on("click",".clip-pass-icon",function(){var a=$(this.dataset.clipboardTarget);clipboard.copy(b.util.decodeEntities(a.val())).then(function(){f.ok(b.config.LANG[45])},function(a){f.error(b.config.LANG[46])})}).on("click",".clip-pass-field",function(){var a=
document.getElementById(this.dataset.clipboardTarget);clipboard.copy(b.util.decodeEntities(a.dataset.pass)).then(function(){f.ok(b.config.LANG[45])},function(a){f.error(b.config.LANG[46])})});else e.warn(b.config.LANG[65])},g=function(a){e.info("encryptFormValue");var c=a.val();if(""!==c&&parseInt(a.attr("data-length"))!==c.length){if(c.length>b.config.PKI.MAX_SIZE)throw a.val(""),"Data length too big for encrypting";c=b.config.PKI.CRYPTO.encrypt(c);a.val(c);a.attr("data-length",c.length)}},p=function(){e.info("checkLogout");
return"login/logout"===n("r")?(f.sticky(b.config.LANG[61],function(){b.util.redirect("index.php?r=login")}),!0):!1},h={current:"",get:function(){e.info("sk:get");return $("#container").attr("data-sk")},set:function(a){e.info("sk:set");e.debug(a);$("#container").attr("data-sk",a);this.current=a}},e={log:function(a){!0===b.config.DEBUG&&console.log(a)},info:function(a){!0===b.config.DEBUG&&console.info(a)},error:function(a){console.error(a)},warn:function(a){console.warn(a)},debug:function(a){!0===
b.config.DEBUG&&console.debug(a)}};Object.freeze(e);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 q=function(){e.info("setupCallbacks");var a=$("#container"),c=a.data("page");if(0<c.length&&"function"===typeof b.triggers.views[c])b.triggers.views[c](a);
0<$("footer").length&&b.triggers.views.footer();$("#btnBack").click(function(){b.util.redirect("index.php")});b.triggers.bodyHooks()},f={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,c){var d={timeOut:0};"function"===typeof c&&(d.onHidden=c);toastr.warning(a,b.config.LANG[60],d)},out:function(a){if("object"===typeof a){var c=a.status,d=a.description;void 0!==a.messages&&0<a.messages.length&&
(d=d+"<br>"+a.messages.join("<br>"));switch(c){case 0:this.ok(d);break;case 1:this.error(d);break;case 2:this.warn(d);break;case 10:b.actions.main.logout();break;case 100:this.ok(d);this.sticky(d);break;case 101:this.error(d);this.sticky(d);break;case 102:this.warn(d);this.sticky(d);break;default:this.error(d)}}},html:{error:function(a){return'<p class="error round">Oops...<br>'+b.config.LANG[1]+"<br>"+a+"</p>"}}};Object.freeze(f);String.format||(String.format=function(a){var c=Array.prototype.slice.call(arguments,
1);return a.replace(/{(\d+)}/g,function(a,b){return"undefined"!==typeof c[b]?c[b]:a})});var r=function(){e.info("getEnvironment");var a=window.location.pathname.split("/"),c=sysPass.Config();c.setAppRoot(window.location.protocol+"//"+window.location.host+function(){for(var c="",b=1;b<=a.length-2;b++)c+="/"+a[b];return c}());var d=b.requests.getRequestOpts();d.url="/index.php?r=bootstrap/getEnvironment";d.method="get";d.useLoading=!1;d.data={isAjax:1};return b.requests.getActionCall(d,function(a){void 0!==
a.data&&(c.setLang(a.data.lang),c.setSessionTimeout(a.data.session_timeout),c.setPkiKey(a.data.pki_key),c.setPkiSize(a.data.pki_max_size),c.setCheckUpdates(a.data.check_updates),c.setCheckNotices(a.data.check_notices),c.setCheckNotifications(a.data.check_notifications),c.setTimezone(a.data.timezone),c.setLocale(a.data.locale),c.setDebugEnabled(a.data.debug),c.setFileMaxSize(a.data.max_file_size),c.setFileAccountAllowedMime(a.data.files_allowed_mime),c.setFileImportAllowedMime(a.data.import_allowed_mime),
c.setCookiesEnabled(a.data.cookies_enabled),c.setPlugins(a.data.plugins),c.setLoggedIn(a.data.loggedin),c.setAuthBasicAutologinEnabled(a.data.authbasic_autologin),c.initialize(),b.config=c.getConfig())}).fail(function(){f.error("Error while getting sysPass config<br/>Please try again or check web server logs")})},b={config:sysPass.Config().getConfig(),actions:sysPass.Actions(e),triggers:sysPass.Triggers(e),util:sysPass.Util(e),theme:{},plugins:{},sk:h,msg:f,log:e,encryptFormValue:g},n=function(a){for(var c=
[],b,e=window.location.href.slice(window.location.href.indexOf("?")+1).split("&"),f=0;f<e.length;f++)b=e[f].split("="),c.push(b[0]),c[b[0]]=b[1];return void 0!==a&&void 0!==c[a]?c[a]:c};return function(){e.info("init");"function"===typeof sysPass.Theme&&(b.theme=sysPass.Theme(e));b.requests=sysPass.Requests(b);r().then(function(){if(!p()&&(b.config.PKI.AVAILABLE&&l(),!1===b.config.BROWSER.COOKIES_ENABLED&&f.sticky(b.config.LANG[64]),m(),q(),0<b.config.PLUGINS.length)){e.info("initPlugins");for(var a=
{},c=0;c<b.config.PLUGINS.length;c++){var d=b.config.PLUGINS[c];"function"===typeof sysPass.Plugins[d]&&(a[d]=sysPass.Plugins[d](b))}b.plugins=a;!0===b.config.AUTH.LOGGEDIN&&!0===b.config.STATUS.CHECK_UPDATES&&k()}Object.freeze(b)});return b}()};

View File

@@ -25,27 +25,11 @@ sysPass.Util = function (log) {
"use strict";
/**
* @author http://stackoverflow.com/users/24950/robert-k
* @author https://stackoverflow.com/users/82548/david-thomas
* @link http://stackoverflow.com/questions/5796718/html-entity-decode
*/
const decodeEntities = function () {
// this prevents any overhead from creating the object each time
const element = document.createElement("div");
function decodeHTMLEntities(str) {
if (str && typeof str === "string") {
// strip script/html tags
str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, "");
str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, "");
element.innerHTML = str;
str = element.textContent;
element.textContent = "";
}
return str;
}
return decodeHTMLEntities;
const decodeEntities = function (str) {
return $('<textarea />').html(str).text();
};
/**

View File

@@ -8,11 +8,11 @@ $jscomp.polyfill("Array.prototype.keys",function(a){return a?a:function(){return
sysPass.Util=function(a){var g={config:{passLength:0,minPasswordLength:8,complexity:{chars:!0,numbers:!0,symbols:!0,uppercase:!0,numlength:12}},random:function(b){a.info("password:random");var c=0,d="",e="";this.config.complexity.symbols&&(d+="!\"\\\u00b7@|#$~%&/()=?'\u00bf\u00a1^*[]\u00b7;,_-{}<>");this.config.complexity.numbers&&(d+="1234567890");this.config.complexity.chars&&(d+="abcdefghijklmnopqrstuvwxyz",this.config.complexity.uppercase&&(d+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"));for(;c++<this.config.complexity.numlength;)e+=
d.charAt(Math.floor(Math.random()*(d.length-1)));this.config.passLength=e.length;"function"===typeof b&&b(e,zxcvbn(e))},output:function(b,c){a.info("password:outputResult");c=$("#password-level-"+c.attr("id"));var d=b.score;c.removeClass("weak good strong strongest");0===this.config.passLength?c.attr("data-level-msg",""):this.config.passLength<this.config.minPasswordLength?c.attr("data-level-msg",sysPassApp.config.LANG[11]).addClass("weak"):0===d?c.attr("data-level-msg",sysPassApp.config.LANG[9]+
" - "+b.feedback.warning).addClass("weak"):1===d||2===d?c.attr("data-level-msg",sysPassApp.config.LANG[8]+" - "+b.feedback.warning).addClass("good"):3===d?c.attr("data-level-msg",sysPassApp.config.LANG[7]).addClass("strong"):4===d&&c.attr("data-level-msg",sysPassApp.config.LANG[10]).addClass("strongest")},checkLevel:function(b){a.info("password:checkPassLevel");this.config.passLength=b.val().length;g.output(zxcvbn(b.val()),b)}},f={state:{lastHash:""},send:function(b,c,d){a.info("sendNotification");
if(!("Notification"in window))a.info("Notifications not supported");else if(d!==f.state.lastHash){var e=function(){a.info("sendNotification:fireMessage");f.state.lastHash=d;var e={};void 0!==c&&(e.body=c);new Notification(b,e)};"granted"===Notification.permission?e():"denied"!==Notification.permission&&Notification.requestPermission().then(function(b){"granted"===b?e():a.info("Notifications disabled")})}}};return{decodeEntities:function(){var a=document.createElement("div");return function(b){b&&
"string"===typeof b&&(b=b.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi,""),b=b.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi,""),a.innerHTML=b,b=a.textContent,a.textContent="");return b}},resizeImage:function(a){var b=.9*$(window).width(),d=.9*$(window).height(),e={width:a.width(),height:a.height()},g={calc:0,main:0,secondary:0,factor:.9,rel:e.width/e.height},f=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,f(a));
return a},h=function(){g.main=b;g.secondary=d;var c=f(g);a.css({width:c.main,height:c.calc});e.width=c.main;e.height=c.calc},k=function(){g.main=d;g.secondary=b;var c=f(g);a.css({width:c.calc,height:c.main});e.width=c.calc;e.height=c.main};e.width>b?h():e.height>d&&k();return e},fileUpload:function(b){var c=function(a){var b=$("#fileUploadForm");!1===a&&b.hide();a=b.find("input[type='file']");a.on("change",function(){"function"===typeof e.beforeSendAction&&e.beforeSendAction();f(this.files)});return a},
d={actionId:b.data("action-id"),itemId:b.data("item-id"),sk:sysPassApp.sk.get()},e={requestDoneAction:"",setRequestData:function(a){$.extend(d,a)},getRequestData:function(){return d},beforeSendAction:"",url:"",allowedMime:[]},g=function(a){if(void 0===e.url||""===e.url)return!1;var b=new FormData;b.append("inFile",a);b.append("isAjax",1);d.sk=sysPassApp.sk.get();Object.keys(d).forEach(function(a){b.append(a,d[a])});a=sysPassApp.requests.getRequestOpts();a.url=e.url;a.processData=!1;a.contentType=
!1;a.data=b;sysPassApp.requests.getActionCall(a,function(a){var b=a.status;a=a.description;0===b?("function"===typeof e.requestDoneAction&&e.requestDoneAction(),sysPassApp.msg.ok(a)):10===b?sysPassApp.appActions().main.logout():sysPassApp.msg.error(a)})},f=function(a){if(5<a.length)sysPassApp.msg.error(sysPassApp.config.LANG[17]+" (Max: 5)");else for(var b=0;b<a.length;b++){var c=a[b];if(c.size/1E3>sysPassApp.config.FILES.MAX_SIZE)sysPassApp.msg.error(sysPassApp.config.LANG[18]+"<br>"+c.name+" (Max: "+
sysPassApp.config.FILES.MAX_SIZE+")");else{a:{var d=void 0;var f=c.type;if(""===f)d=!0;else{for(d in e.allowedMime)if(-1!==f.indexOf(e.allowedMime[d])){d=!0;break a}d=!1}}d?g(a[b]):sysPassApp.msg.error(sysPassApp.config.LANG[19]+"<br>"+c.type)}}},h=function(){a.info("fileUpload:init");var d=c(!1);b.on("dragover dragenter",function(b){a.info("fileUpload:drag");b.stopPropagation();b.preventDefault()});b.on("drop",function(b){a.info("fileUpload:drop");b.stopPropagation();b.preventDefault();"function"===
typeof e.beforeSendAction&&e.beforeSendAction();f(b.originalEvent.dataTransfer.files)});b.on("click",function(){d.click()})};window.File&&window.FileList&&window.FileReader?h():c(!0);return e},scrollUp:function(){$("html, body").animate({scrollTop:0},"slow")},setContentSize:function(){var a=$("#container");a.hasClass("content-no-auto-resize")||a.css("height",$("#content").height()+200)},redirect:function(a){window.location.replace(a)},uniqueId:function(){var a=String.fromCharCode(Math.floor(25*Math.random()+
65));do{var c=Math.floor(42*Math.random()+48);if(58>c||64<c)a+=String.fromCharCode(c)}while(32>a.length);return a.toLowerCase()},getUrl:function(a,c){return a+"?"+Object.keys(c).map(function(a){return Array.isArray(c[a])?a+"="+c[a].join("/"):a+"="+c[a]}).join("&")},focus:function(b){a.debug("focus");b.find("input:not([id*=selectized]):visible:first").focus()},sendNotification:f.send,password:g,hash:{md5:function(a){return SparkMD5.hash(a,!1)}}}};
if(!("Notification"in window))a.info("Notifications not supported");else if(d!==f.state.lastHash){var e=function(){a.info("sendNotification:fireMessage");f.state.lastHash=d;var e={};void 0!==c&&(e.body=c);new Notification(b,e)};"granted"===Notification.permission?e():"denied"!==Notification.permission&&Notification.requestPermission().then(function(b){"granted"===b?e():a.info("Notifications disabled")})}}};return{decodeEntities:function(a){return $("<textarea />").html(a).text()},resizeImage:function(a){var b=
.9*$(window).width(),d=.9*$(window).height(),e={width:a.width(),height:a.height()},g={calc:0,main:0,secondary:0,factor:.9,rel:e.width/e.height},f=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,f(a));return a},h=function(){g.main=b;g.secondary=d;var c=f(g);a.css({width:c.main,height:c.calc});e.width=c.main;e.height=c.calc},k=function(){g.main=d;g.secondary=b;var c=f(g);a.css({width:c.calc,height:c.main});e.width=c.calc;
e.height=c.main};e.width>b?h():e.height>d&&k();return e},fileUpload:function(b){var c=function(a){var b=$("#fileUploadForm");!1===a&&b.hide();a=b.find("input[type='file']");a.on("change",function(){"function"===typeof e.beforeSendAction&&e.beforeSendAction();f(this.files)});return a},d={actionId:b.data("action-id"),itemId:b.data("item-id"),sk:sysPassApp.sk.get()},e={requestDoneAction:"",setRequestData:function(a){$.extend(d,a)},getRequestData:function(){return d},beforeSendAction:"",url:"",allowedMime:[]},
g=function(a){if(void 0===e.url||""===e.url)return!1;var b=new FormData;b.append("inFile",a);b.append("isAjax",1);d.sk=sysPassApp.sk.get();Object.keys(d).forEach(function(a){b.append(a,d[a])});a=sysPassApp.requests.getRequestOpts();a.url=e.url;a.processData=!1;a.contentType=!1;a.data=b;sysPassApp.requests.getActionCall(a,function(a){var b=a.status;a=a.description;0===b?("function"===typeof e.requestDoneAction&&e.requestDoneAction(),sysPassApp.msg.ok(a)):10===b?sysPassApp.appActions().main.logout():
sysPassApp.msg.error(a)})},f=function(a){if(5<a.length)sysPassApp.msg.error(sysPassApp.config.LANG[17]+" (Max: 5)");else for(var b=0;b<a.length;b++){var c=a[b];if(c.size/1E3>sysPassApp.config.FILES.MAX_SIZE)sysPassApp.msg.error(sysPassApp.config.LANG[18]+"<br>"+c.name+" (Max: "+sysPassApp.config.FILES.MAX_SIZE+")");else{a:{var d=void 0;var f=c.type;if(""===f)d=!0;else{for(d in e.allowedMime)if(-1!==f.indexOf(e.allowedMime[d])){d=!0;break a}d=!1}}d?g(a[b]):sysPassApp.msg.error(sysPassApp.config.LANG[19]+
"<br>"+c.type)}}},h=function(){a.info("fileUpload:init");var d=c(!1);b.on("dragover dragenter",function(b){a.info("fileUpload:drag");b.stopPropagation();b.preventDefault()});b.on("drop",function(b){a.info("fileUpload:drop");b.stopPropagation();b.preventDefault();"function"===typeof e.beforeSendAction&&e.beforeSendAction();f(b.originalEvent.dataTransfer.files)});b.on("click",function(){d.click()})};window.File&&window.FileList&&window.FileReader?h():c(!0);return e},scrollUp:function(){$("html, body").animate({scrollTop:0},
"slow")},setContentSize:function(){var a=$("#container");a.hasClass("content-no-auto-resize")||a.css("height",$("#content").height()+200)},redirect:function(a){window.location.replace(a)},uniqueId:function(){var a=String.fromCharCode(Math.floor(25*Math.random()+65));do{var c=Math.floor(42*Math.random()+48);if(58>c||64<c)a+=String.fromCharCode(c)}while(32>a.length);return a.toLowerCase()},getUrl:function(a,c){return a+"?"+Object.keys(c).map(function(a){return Array.isArray(c[a])?a+"="+c[a].join("/"):
a+"="+c[a]}).join("&")},focus:function(b){a.debug("focus");b.find("input:not([id*=selectized]):visible:first").focus()},sendNotification:f.send,password:g,hash:{md5:function(a){return SparkMD5.hash(a,!1)}}}};