diff --git a/.gitignore b/.gitignore
index 124173aa..0a7a3772 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,6 +52,7 @@ app/temp/*
app/plugins/*
app/modules/**/plugins/*
!app/config/actions.xml
+!app/config/mime.xml
!app/config/*.inc
res/*
tools/
diff --git a/app/config/mime.xml b/app/config/mime.xml
new file mode 100644
index 00000000..93484ee4
--- /dev/null
+++ b/app/config/mime.xml
@@ -0,0 +1,209 @@
+
+
+
+
+ application/x-abiword
+ AbiWord document
+ abw
+
+
+ application/octet-stream
+ Archive document (multiple files embedded)
+ arc
+
+
+ application/vnd.amazon.ebook
+ Amazon Kindle eBook format
+ azw
+
+
+ application/octet-stream
+ Any kind of binary data
+ bin
+
+
+ image/bmp
+ Windows OS/2 Bitmap Graphics
+ bmp
+
+
+ application/x-bzip
+ BZip archive
+ bz
+
+
+ application/x-bzip2
+ BZip2 archive
+ bz2
+
+
+ application/x-csh
+ C-Shell script
+ csh
+
+
+ text/csv
+ Comma-separated values (CSV)
+ csv
+
+
+ application/msword
+ Microsoft Word
+ doc
+
+
+ application/vnd.openxmlformats-officedocument.wordprocessingml.document
+ Microsoft Word (OpenXML)
+ docx
+
+
+ application/vnd.ms-fontobject
+ MS Embedded OpenType fonts
+ eot
+
+
+ application/epub+zip
+ Electronic publication (EPUB)
+ epub
+
+
+ image/gif
+ Graphics Interchange Format (GIF)
+ gif
+
+
+ text/html
+ HyperText Markup Language (HTML)
+ html
+
+
+ text/calendar
+ iCalendar format
+ ics
+
+
+ application/java-archive
+ Java Archive (JAR)
+ jar
+
+
+ image/jpeg
+ JPEG images
+ jpg
+
+
+ application/json
+ JSON format
+ json
+
+
+ application/vnd.apple.installer+xml
+ Apple Installer Package
+ mpkg
+
+
+ application/vnd.oasis.opendocument.presentation
+ OpenDocument presentation document
+ odp
+
+
+ application/vnd.oasis.opendocument.spreadsheet
+ OpenDocument spreadsheet document
+ ods
+
+
+ application/vnd.oasis.opendocument.text
+ OpenDocument text document
+ odt
+
+
+ image/png
+ Portable Network Graphics
+ png
+
+
+ application/pdf
+ Adobe Portable Document Format (PDF)
+ pdf
+
+
+ application/vnd.ms-powerpoint
+ Microsoft PowerPoint
+ ppt
+
+
+ application/vnd.openxmlformats-officedocument.presentationml.presentation
+ Microsoft PowerPoint (OpenXML)
+ pptx
+
+
+ application/x-rar-compressed
+ RAR archive
+ rar
+
+
+ application/rtf
+ Rich Text Format (RTF)
+ rtf
+
+
+ application/x-sh
+ Bourne shell script
+ sh
+
+
+ image/svg+xml
+ Scalable Vector Graphics (SVG)
+ svg
+
+
+ application/x-tar
+ Tape Archive (TAR)
+ tar
+
+
+ text/plain
+ Text, (generally ASCII or ISO 8859-n)
+ txt
+
+
+ application/vnd.visio
+ Microsoft Visio
+ vsd
+
+
+ application/xhtml+xml
+ XHTML
+ xhtml
+
+
+ application/vnd.ms-excel
+ Microsoft Excel
+ xls
+
+
+ application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
+ Microsoft Excel (OpenXML)
+ xlsx
+
+
+ application/xml
+ XML
+ xml
+
+
+ application/vnd.mozilla.xul+xml
+ XUL
+ xul
+
+
+ application/zip
+ ZIP archive
+ zip
+
+
+ application/x-7z-compressed
+ 7-zip archive
+ 7z
+
+
diff --git a/app/config/strings.js.inc b/app/config/strings.js.inc
index c8475afe..e7eb04dc 100644
--- a/app/config/strings.js.inc
+++ b/app/config/strings.js.inc
@@ -42,7 +42,7 @@ return [
16 => __('Your browser does not support HTML5 file uploads'),
17 => __('Too many files'),
18 => __('File size not allowed'),
- 19 => __('Extension not allowed'),
+ 19 => __('MIME type not allowed'),
20 => __('Clear the event log out?'),
21 => __('Select Group'),
22 => __('Select User'),
diff --git a/app/modules/web/Controllers/AccountController.php b/app/modules/web/Controllers/AccountController.php
index 4b600490..34152a5b 100644
--- a/app/modules/web/Controllers/AccountController.php
+++ b/app/modules/web/Controllers/AccountController.php
@@ -92,6 +92,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e);
}
}
@@ -115,6 +117,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -163,6 +167,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -239,6 +245,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e, 'account-link');
}
}
@@ -320,6 +328,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -368,6 +378,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -413,6 +425,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e, 'account');
}
}
@@ -458,6 +472,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e, 'account-editpass');
}
}
@@ -503,6 +519,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e, 'account-history');
}
}
@@ -537,6 +555,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
ErrorUtil::showExceptionInView($this->view, $e, 'account-request');
}
}
@@ -578,6 +598,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -636,6 +658,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -762,6 +786,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -809,6 +835,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -852,6 +880,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -891,6 +921,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -936,6 +968,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -986,6 +1020,8 @@ final class AccountController extends ControllerBase implements CrudControllerIn
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/AccountFavoriteController.php b/app/modules/web/Controllers/AccountFavoriteController.php
index b93996d2..0f2c3f7f 100644
--- a/app/modules/web/Controllers/AccountFavoriteController.php
+++ b/app/modules/web/Controllers/AccountFavoriteController.php
@@ -24,6 +24,7 @@
namespace SP\Modules\Web\Controllers;
+use SP\Core\Events\Event;
use SP\Http\JsonResponse;
use SP\Modules\Web\Controllers\Traits\JsonTrait;
use SP\Services\Account\AccountToFavoriteService;
@@ -56,6 +57,8 @@ final class AccountFavoriteController extends SimpleControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -74,6 +77,8 @@ final class AccountFavoriteController extends SimpleControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/AccountFileController.php b/app/modules/web/Controllers/AccountFileController.php
index 2372f3cd..bcc8e227 100644
--- a/app/modules/web/Controllers/AccountFileController.php
+++ b/app/modules/web/Controllers/AccountFileController.php
@@ -37,10 +37,10 @@ use SP\Modules\Web\Controllers\Traits\JsonTrait;
use SP\Mvc\Controller\CrudControllerInterface;
use SP\Services\Account\AccountFileService;
use SP\Services\Account\AccountService;
+use SP\Storage\File\FileException;
use SP\Storage\File\FileHandler;
use SP\Util\ErrorUtil;
use SP\Util\FileUtil;
-use SP\Util\Util;
/**
* Class AccountFileController
@@ -49,7 +49,7 @@ use SP\Util\Util;
*/
final class AccountFileController extends ControllerBase implements CrudControllerInterface
{
- const EXTENSIONS_VIEW = ['TXT'];
+ const MIME_VIEW = ['text/plain'];
use JsonTrait, ItemTrait;
@@ -91,10 +91,10 @@ final class AccountFileController extends ControllerBase implements CrudControll
return $this->returnJsonResponseData(['html' => $this->render()]);
}
- $extension = mb_strtoupper($fileData->getExtension());
+ $type = strtolower($fileData->getType());
- if (in_array($extension, self::EXTENSIONS_VIEW)) {
- $this->view->assign('extension', $extension);
+ if (in_array($type, self::MIME_VIEW)) {
+ $this->view->assign('mime', $type);
$this->view->assign('data', htmlentities($fileData->getContent()));
$this->eventDispatcher->notifyEvent('show.accountFile',
@@ -109,6 +109,8 @@ final class AccountFileController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
@@ -148,9 +150,9 @@ final class AccountFileController extends ControllerBase implements CrudControll
$response->header('Content-Description', ' sysPass file');
$response->header('Content-transfer-encoding', 'binary');
- $extension = mb_strtoupper($fileData->getExtension());
+ $type = strtolower($fileData->getType());
- if ($extension === 'PDF') {
+ if ($type === 'application/pdf') {
$response->header('Content-Disposition', 'inline; filename="' . $fileData->getName() . '"');
} else {
$response->header('Set-Cookie', 'fileDownload=true; path=/');
@@ -186,61 +188,46 @@ final class AccountFileController extends ControllerBase implements CrudControll
throw new SPException(__u('INVALID QUERY'), SPException::ERROR);
}
- $allowedExts = $this->configData->getFilesAllowedExts();
+ $filesAllowedMime = $this->configData->getFilesAllowedMime();
- if (empty($allowedExts)) {
- throw new SPException(__u('There aren\'t any allowed extensions'), SPException::ERROR);
+ if (empty($filesAllowedMime)) {
+ throw new SPException(__u('There aren\'t any allowed mime types'));
}
- $fileHandler = new FileHandler($file['tmp_name']);
+ try {
+ $fileHandler = new FileHandler($file['tmp_name']);
- $fileData = new FileData();
- $fileData->setAccountId($accountId);
- $fileData->setName(Html::sanitize($file['name']));
- $fileData->setSize($file['size']);
- $fileData->setType($file['type']);
-
- if ($fileData->getName() !== '') {
- // Comprobamos la extensión del archivo
+ $fileData = new FileData();
+ $fileData->setAccountId($accountId);
+ $fileData->setName(Html::sanitize($file['name']));
+ $fileData->setSize($file['size']);
+ $fileData->setType($file['type']);
$fileData->setExtension(mb_strtoupper(pathinfo($fileData->getName(), PATHINFO_EXTENSION)));
- if (!in_array($fileData->getExtension(), $allowedExts, true)) {
+ if ($fileData->getName() === '') {
throw new SPException(
- __u('File type not allowed'),
+ __u('Invalid file'),
SPException::ERROR,
- sprintf(__('Extension: %s'), $fileData->getExtension())
+ sprintf(__u('File: %s'), $fileData->getName())
);
}
- } else {
- throw new SPException(
- __u('Invalid file'),
- SPException::ERROR,
- sprintf(__u('File: %s'), $fileData->getName())
- );
- }
- if (!file_exists($file['tmp_name'])) {
- throw new SPException(
- __u('Internal error while reading the file'),
- SPException::ERROR,
- sprintf(__u('Maximum size: %s'), Util::getMaxUpload())
- );
- }
+ $fileHandler->checkFileExists();
- $allowedSize = $this->configData->getFilesAllowedSize();
+ $this->checkAllowedMimeType($fileData, $fileHandler);
- if ($fileData->getSize() > ($allowedSize * 1000)) {
- throw new SPException(
- __u('File size exceeded'),
- SPException::ERROR,
- sprintf(__u('Maximum size: %d KB'),
- $fileData->getRoundSize())
- );
- }
+ $allowedSize = $this->configData->getFilesAllowedSize();
- $fileData->setContent($fileHandler->readToString());
+ if ($fileData->getSize() > ($allowedSize * 1000)) {
+ throw new SPException(
+ __u('File size exceeded'),
+ SPException::ERROR,
+ sprintf(__u('Maximum size: %d KB'), $fileData->getRoundSize())
+ );
+ }
- if ($fileData->getContent() === false) {
+ $fileData->setContent($fileHandler->readToString());
+ } catch (FileException $e) {
throw new SPException(__u('Internal error while reading the file'));
}
@@ -266,14 +253,39 @@ final class AccountFileController extends ControllerBase implements CrudControll
} catch (SPException $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponse(1, $e->getMessage(), [$e->getHint()]);
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
+ /**
+ * @param FileData $fileData
+ *
+ * @param FileHandler $fileHandler
+ *
+ * @throws SPException
+ * @throws \SP\Storage\File\FileException
+ */
+ private function checkAllowedMimeType(FileData $fileData, FileHandler $fileHandler)
+ {
+ if (!in_array($fileData->getType(), $this->configData->getFilesAllowedMime())
+ && !in_array($fileHandler->getFileType(), $this->configData->getFilesAllowedMime())
+ ) {
+ throw new SPException(
+ __u('File type not allowed'),
+ SPException::ERROR,
+ sprintf(__('MIME type: %s'), $fileData->getType())
+ );
+ }
+ }
+
/**
* Search action
*
@@ -370,6 +382,8 @@ final class AccountFileController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/AccountHistoryManagerController.php b/app/modules/web/Controllers/AccountHistoryManagerController.php
index 7b2bbc7d..0d0cc363 100644
--- a/app/modules/web/Controllers/AccountHistoryManagerController.php
+++ b/app/modules/web/Controllers/AccountHistoryManagerController.php
@@ -125,6 +125,8 @@ final class AccountHistoryManagerController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -162,6 +164,8 @@ final class AccountHistoryManagerController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/AuthTokenController.php b/app/modules/web/Controllers/AuthTokenController.php
index 58a9a139..a3b7efea 100644
--- a/app/modules/web/Controllers/AuthTokenController.php
+++ b/app/modules/web/Controllers/AuthTokenController.php
@@ -123,6 +123,8 @@ final class AuthTokenController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -189,6 +191,8 @@ final class AuthTokenController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -238,6 +242,8 @@ final class AuthTokenController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -272,6 +278,8 @@ final class AuthTokenController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -324,6 +332,8 @@ final class AuthTokenController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -360,6 +370,8 @@ final class AuthTokenController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/BootstrapController.php b/app/modules/web/Controllers/BootstrapController.php
index 74deb497..874b8a67 100644
--- a/app/modules/web/Controllers/BootstrapController.php
+++ b/app/modules/web/Controllers/BootstrapController.php
@@ -69,8 +69,8 @@ final class BootstrapController extends SimpleControllerBase
'authbasic_autologin' => $this->getAuthBasicAutologinEnabled(),
'pki_key' => $this->getPublicKey(),
'pki_max_size' => CryptPKI::getMaxDataSize(),
- 'import_allowed_exts' => ImportService::ALLOWED_EXTS,
- 'files_allowed_exts' => $this->configData->getFilesAllowedExts(),
+ 'import_allowed_mime' => ImportService::ALLOWED_MIME,
+ 'files_allowed_mime' => $this->configData->getFilesAllowedMime(),
'session_timeout' => $this->configData->getSessionTimeout()
];
diff --git a/app/modules/web/Controllers/CategoryController.php b/app/modules/web/Controllers/CategoryController.php
index 1ead5405..d03af2e5 100644
--- a/app/modules/web/Controllers/CategoryController.php
+++ b/app/modules/web/Controllers/CategoryController.php
@@ -118,6 +118,8 @@ final class CategoryController extends ControllerBase implements CrudControllerI
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -183,6 +185,8 @@ final class CategoryController extends ControllerBase implements CrudControllerI
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -232,6 +236,8 @@ final class CategoryController extends ControllerBase implements CrudControllerI
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -270,6 +276,8 @@ final class CategoryController extends ControllerBase implements CrudControllerI
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -312,6 +320,8 @@ final class CategoryController extends ControllerBase implements CrudControllerI
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -343,6 +353,8 @@ final class CategoryController extends ControllerBase implements CrudControllerI
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/ClientController.php b/app/modules/web/Controllers/ClientController.php
index 8d287fef..8fafe724 100644
--- a/app/modules/web/Controllers/ClientController.php
+++ b/app/modules/web/Controllers/ClientController.php
@@ -119,6 +119,8 @@ final class ClientController extends ControllerBase implements CrudControllerInt
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -183,6 +185,8 @@ final class ClientController extends ControllerBase implements CrudControllerInt
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -229,6 +233,8 @@ final class ClientController extends ControllerBase implements CrudControllerInt
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -265,6 +271,8 @@ final class ClientController extends ControllerBase implements CrudControllerInt
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -303,6 +311,8 @@ final class ClientController extends ControllerBase implements CrudControllerInt
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -334,6 +344,8 @@ final class ClientController extends ControllerBase implements CrudControllerInt
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/ConfigAccountController.php b/app/modules/web/Controllers/ConfigAccountController.php
index c9c601ed..471469b5 100644
--- a/app/modules/web/Controllers/ConfigAccountController.php
+++ b/app/modules/web/Controllers/ConfigAccountController.php
@@ -24,7 +24,6 @@
namespace SP\Modules\Web\Controllers;
-use SP\Config\ConfigUtil;
use SP\Core\Acl\ActionsInterface;
use SP\Core\Acl\UnauthorizedPageException;
use SP\Core\Events\Event;
@@ -75,7 +74,7 @@ final class ConfigAccountController extends SimpleControllerBase
}
$configData->setFilesEnabled(true);
- $configData->setFilesAllowedExts(ConfigUtil::filesExtsAdapter($this->request->analyzeString('files_allowed_exts')));
+ $configData->setFilesAllowedMime($this->request->analyzeArray('files_allowed_mimetypes'));
$configData->setFilesAllowedSize($filesAllowedSize);
if ($configData->isFilesEnabled() === false) {
diff --git a/app/modules/web/Controllers/ConfigImportController.php b/app/modules/web/Controllers/ConfigImportController.php
index 1a1c2b28..274ff2e7 100644
--- a/app/modules/web/Controllers/ConfigImportController.php
+++ b/app/modules/web/Controllers/ConfigImportController.php
@@ -86,10 +86,7 @@ final class ConfigImportController extends SimpleControllerBase
} catch (\Exception $e) {
processException($e);
- $this->eventDispatcher->notifyEvent('exception',
- new Event($e, EventMessage::factory()
- ->addDescription($e->getMessage()))
- );
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
return $this->returnJsonResponseException($e);
}
diff --git a/app/modules/web/Controllers/ConfigLdapController.php b/app/modules/web/Controllers/ConfigLdapController.php
index e6eb42c9..2885f313 100644
--- a/app/modules/web/Controllers/ConfigLdapController.php
+++ b/app/modules/web/Controllers/ConfigLdapController.php
@@ -101,6 +101,10 @@ final class ConfigLdapController extends SimpleControllerBase
$this->eventDispatcher->notifyEvent('save.config.ldap', new Event($this, $eventMessage));
});
} catch (\Exception $e) {
+ processException($e);
+
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -161,8 +165,9 @@ final class ConfigLdapController extends SimpleControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
-// $this->JsonResponse->addMessage(__('Revise el registro de eventos para más detalles', false));
}
}
@@ -206,8 +211,9 @@ final class ConfigLdapController extends SimpleControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
-// $this->JsonResponse->addMessage(__('Revise el registro de eventos para más detalles', false));
}
}
@@ -284,6 +290,8 @@ final class ConfigLdapController extends SimpleControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/ConfigManagerController.php b/app/modules/web/Controllers/ConfigManagerController.php
index 651fda9b..8483c806 100644
--- a/app/modules/web/Controllers/ConfigManagerController.php
+++ b/app/modules/web/Controllers/ConfigManagerController.php
@@ -29,6 +29,7 @@ use SP\Core\AppInfoInterface;
use SP\Core\Crypt\CryptSessionHandler;
use SP\Core\Events\Event;
use SP\Core\Language;
+use SP\Core\MimeTypes;
use SP\Modules\Web\Controllers\Helpers\TabsHelper;
use SP\Mvc\View\Components\DataTab;
use SP\Mvc\View\Components\SelectItemAdapter;
@@ -162,7 +163,10 @@ final class ConfigManagerController extends ControllerBase
/**
* @return DataTab
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
* @throws \SP\Core\Exceptions\CheckException
+ * @throws \SP\Core\Exceptions\SPException
*/
protected function getAccountConfig()
{
@@ -171,6 +175,19 @@ final class ConfigManagerController extends ControllerBase
$template->addTemplate('accounts');
$template->assign('gdIsAvailable', $this->extensionChecker->checkGdAvailable());
+ $mimeTypesAvailable = array_map(function ($value) {
+ return $value['type'];
+ }, $this->dic->get(MimeTypes::class)->getMimeTypes());
+
+ $mimeTypes = SelectItemAdapter::factory(
+ array_merge($mimeTypesAvailable, $this->configData->getFilesAllowedMime())
+ );
+
+ $template->assign('mimeTypes', $mimeTypes->getItemsFromArraySelected(
+ $this->configData->getFilesAllowedMime(),
+ true)
+ );
+
return new DataTab(__('Accounts'), $template);
}
@@ -263,7 +280,9 @@ final class ConfigManagerController extends ControllerBase
$template->assign('tempMasterPassTime', $configService->getByParam(TemporaryMasterPassService::PARAM_TIME, 0));
$template->assign('tempMasterMaxTime', $configService->getByParam(TemporaryMasterPassService::PARAM_MAX_TIME, 0));
- $tempMasterAttempts = sprintf('%d/%d', $configService->getByParam(TemporaryMasterPassService::PARAM_ATTEMPTS, 0), TemporaryMasterPassService::MAX_ATTEMPTS);
+ $tempMasterAttempts = sprintf('%d/%d',
+ $configService->getByParam(TemporaryMasterPassService::PARAM_ATTEMPTS, 0),
+ TemporaryMasterPassService::MAX_ATTEMPTS);
$template->assign('tempMasterAttempts', $tempMasterAttempts);
$template->assign('tempMasterPass', $this->session->getTemporaryMasterPass());
@@ -325,8 +344,14 @@ final class ConfigManagerController extends ControllerBase
$template->setBase('config');
$template->addTemplate('import');
- $template->assign('userGroups', SelectItemAdapter::factory(UserGroupService::getItemsBasic())->getItemsFromModelSelected([$this->userData->getUserGroupId()]));
- $template->assign('users', SelectItemAdapter::factory(UserService::getItemsBasic())->getItemsFromModelSelected([$this->userData->getId()]));
+ $template->assign('userGroups', SelectItemAdapter::factory(
+ UserGroupService::getItemsBasic())
+ ->getItemsFromModelSelected([$this->userData->getUserGroupId()])
+ );
+ $template->assign('users', SelectItemAdapter::factory(
+ UserService::getItemsBasic())
+ ->getItemsFromModelSelected([$this->userData->getId()])
+ );
return new DataTab(__('Import Accounts'), $template);
}
diff --git a/app/modules/web/Controllers/CustomFieldController.php b/app/modules/web/Controllers/CustomFieldController.php
index 49926100..da43788b 100644
--- a/app/modules/web/Controllers/CustomFieldController.php
+++ b/app/modules/web/Controllers/CustomFieldController.php
@@ -120,6 +120,8 @@ final class CustomFieldController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -182,6 +184,8 @@ final class CustomFieldController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -220,6 +224,8 @@ final class CustomFieldController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -255,6 +261,8 @@ final class CustomFieldController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -294,6 +302,8 @@ final class CustomFieldController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -323,6 +333,8 @@ final class CustomFieldController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponse(JsonResponse::JSON_ERROR, $e->getMessage());
}
diff --git a/app/modules/web/Controllers/ItemPresetController.php b/app/modules/web/Controllers/ItemPresetController.php
index 785a01da..ef72ff92 100644
--- a/app/modules/web/Controllers/ItemPresetController.php
+++ b/app/modules/web/Controllers/ItemPresetController.php
@@ -81,6 +81,8 @@ final class ItemPresetController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -216,6 +218,8 @@ final class ItemPresetController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -248,6 +252,8 @@ final class ItemPresetController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -293,6 +299,8 @@ final class ItemPresetController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -330,6 +338,8 @@ final class ItemPresetController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -371,6 +381,8 @@ final class ItemPresetController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/LoginController.php b/app/modules/web/Controllers/LoginController.php
index dd9b6a3f..59c6ed57 100644
--- a/app/modules/web/Controllers/LoginController.php
+++ b/app/modules/web/Controllers/LoginController.php
@@ -149,7 +149,6 @@ final class LoginController extends ControllerBase
->getCustomLayout('index', 'login');
$this->view->assign('mailEnabled', $this->configData->isMailEnabled());
-// $this->view->assign('updated', SessionFactory::getAppUpdated());
$this->prepareSignedUriOnView();
diff --git a/app/modules/web/Controllers/NotificationController.php b/app/modules/web/Controllers/NotificationController.php
index d19b7e80..3b0b5361 100644
--- a/app/modules/web/Controllers/NotificationController.php
+++ b/app/modules/web/Controllers/NotificationController.php
@@ -121,6 +121,8 @@ final class NotificationController extends ControllerBase implements CrudControl
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -203,6 +205,8 @@ final class NotificationController extends ControllerBase implements CrudControl
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -235,6 +239,8 @@ final class NotificationController extends ControllerBase implements CrudControl
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -288,6 +294,8 @@ final class NotificationController extends ControllerBase implements CrudControl
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -321,6 +329,8 @@ final class NotificationController extends ControllerBase implements CrudControl
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -352,6 +362,8 @@ final class NotificationController extends ControllerBase implements CrudControl
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -387,6 +399,8 @@ final class NotificationController extends ControllerBase implements CrudControl
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/PluginController.php b/app/modules/web/Controllers/PluginController.php
index cdabfa6f..44d3c1e0 100644
--- a/app/modules/web/Controllers/PluginController.php
+++ b/app/modules/web/Controllers/PluginController.php
@@ -144,6 +144,8 @@ final class PluginController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -203,6 +205,8 @@ final class PluginController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -230,6 +234,8 @@ final class PluginController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -257,6 +263,8 @@ final class PluginController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -293,6 +301,8 @@ final class PluginController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/PublicLinkController.php b/app/modules/web/Controllers/PublicLinkController.php
index 8daf966c..aac032a8 100644
--- a/app/modules/web/Controllers/PublicLinkController.php
+++ b/app/modules/web/Controllers/PublicLinkController.php
@@ -123,6 +123,8 @@ final class PublicLinkController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -181,6 +183,8 @@ final class PublicLinkController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -213,6 +217,8 @@ final class PublicLinkController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -260,6 +266,8 @@ final class PublicLinkController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -289,6 +297,8 @@ final class PublicLinkController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -324,6 +334,8 @@ final class PublicLinkController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -365,6 +377,8 @@ final class PublicLinkController extends ControllerBase implements CrudControlle
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/TagController.php b/app/modules/web/Controllers/TagController.php
index 4e363ac6..e8da64ac 100644
--- a/app/modules/web/Controllers/TagController.php
+++ b/app/modules/web/Controllers/TagController.php
@@ -117,6 +117,8 @@ final class TagController extends ControllerBase implements CrudControllerInterf
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -177,6 +179,8 @@ final class TagController extends ControllerBase implements CrudControllerInterf
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -217,6 +221,8 @@ final class TagController extends ControllerBase implements CrudControllerInterf
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -246,6 +252,8 @@ final class TagController extends ControllerBase implements CrudControllerInterf
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -279,6 +287,8 @@ final class TagController extends ControllerBase implements CrudControllerInterf
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -310,6 +320,8 @@ final class TagController extends ControllerBase implements CrudControllerInterf
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/TrackController.php b/app/modules/web/Controllers/TrackController.php
index 9eaa64f5..a34e547c 100644
--- a/app/modules/web/Controllers/TrackController.php
+++ b/app/modules/web/Controllers/TrackController.php
@@ -115,6 +115,8 @@ final class TrackController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -141,6 +143,8 @@ final class TrackController extends ControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/UserController.php b/app/modules/web/Controllers/UserController.php
index 5632de52..e67fbfe6 100644
--- a/app/modules/web/Controllers/UserController.php
+++ b/app/modules/web/Controllers/UserController.php
@@ -124,6 +124,8 @@ final class UserController extends ControllerBase implements CrudControllerInter
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -209,6 +211,8 @@ final class UserController extends ControllerBase implements CrudControllerInter
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -246,6 +250,8 @@ final class UserController extends ControllerBase implements CrudControllerInter
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -292,6 +298,8 @@ final class UserController extends ControllerBase implements CrudControllerInter
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -331,6 +339,8 @@ final class UserController extends ControllerBase implements CrudControllerInter
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -396,6 +406,8 @@ final class UserController extends ControllerBase implements CrudControllerInter
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -435,6 +447,8 @@ final class UserController extends ControllerBase implements CrudControllerInter
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -466,6 +480,8 @@ final class UserController extends ControllerBase implements CrudControllerInter
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/UserGroupController.php b/app/modules/web/Controllers/UserGroupController.php
index 47b9d22f..7656c74b 100644
--- a/app/modules/web/Controllers/UserGroupController.php
+++ b/app/modules/web/Controllers/UserGroupController.php
@@ -126,6 +126,8 @@ final class UserGroupController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -197,6 +199,8 @@ final class UserGroupController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -243,6 +247,8 @@ final class UserGroupController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -280,6 +286,8 @@ final class UserGroupController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -321,6 +329,8 @@ final class UserGroupController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -352,6 +362,8 @@ final class UserGroupController extends ControllerBase implements CrudController
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/UserPassResetController.php b/app/modules/web/Controllers/UserPassResetController.php
index 13106a0f..c05a647a 100644
--- a/app/modules/web/Controllers/UserPassResetController.php
+++ b/app/modules/web/Controllers/UserPassResetController.php
@@ -112,6 +112,8 @@ final class UserPassResetController extends ControllerBase
$this->addTracking();
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -203,6 +205,8 @@ final class UserPassResetController extends ControllerBase
$this->addTracking();
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/UserProfileController.php b/app/modules/web/Controllers/UserProfileController.php
index 8567cc56..3f99151b 100644
--- a/app/modules/web/Controllers/UserProfileController.php
+++ b/app/modules/web/Controllers/UserProfileController.php
@@ -119,6 +119,8 @@ final class UserProfileController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -186,6 +188,8 @@ final class UserProfileController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -232,6 +236,8 @@ final class UserProfileController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -265,6 +271,8 @@ final class UserProfileController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -303,6 +311,8 @@ final class UserProfileController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
@@ -334,6 +344,8 @@ final class UserProfileController extends ControllerBase implements CrudControll
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
diff --git a/app/modules/web/Controllers/UserSettingsGeneralController.php b/app/modules/web/Controllers/UserSettingsGeneralController.php
index 00783d8c..47372d90 100644
--- a/app/modules/web/Controllers/UserSettingsGeneralController.php
+++ b/app/modules/web/Controllers/UserSettingsGeneralController.php
@@ -24,6 +24,7 @@
namespace SP\Modules\Web\Controllers;
+use SP\Core\Events\Event;
use SP\Http\JsonResponse;
use SP\Modules\Web\Controllers\Traits\JsonTrait;
use SP\Services\User\UserService;
@@ -75,12 +76,17 @@ final class UserSettingsGeneralController extends SimpleControllerBase
} catch (\Exception $e) {
processException($e);
+ $this->eventDispatcher->notifyEvent('exception', new Event($e));
+
return $this->returnJsonResponseException($e);
}
}
/**
* initialize
+ *
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
protected function initialize()
{
diff --git a/app/modules/web/Controllers/UserSettingsManagerController.php b/app/modules/web/Controllers/UserSettingsManagerController.php
index 8d74cb0b..568b68fa 100644
--- a/app/modules/web/Controllers/UserSettingsManagerController.php
+++ b/app/modules/web/Controllers/UserSettingsManagerController.php
@@ -46,6 +46,10 @@ final class UserSettingsManagerController extends ControllerBase implements Exte
*/
protected $tabsHelper;
+ /**
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
+ */
public function indexAction()
{
$this->getTabs();
@@ -53,6 +57,9 @@ final class UserSettingsManagerController extends ControllerBase implements Exte
/**
* Returns a tabbed grid with items
+ *
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
*/
protected function getTabs()
{
diff --git a/app/modules/web/themes/material-blue/views/config/accounts.inc b/app/modules/web/themes/material-blue/views/config/accounts.inc
index c460abdc..726adcf0 100644
--- a/app/modules/web/themes/material-blue/views/config/accounts.inc
+++ b/app/modules/web/themes/material-blue/views/config/accounts.inc
@@ -304,23 +304,30 @@
-
-
+ getIconHelp()->getIcon(); ?>
- |
-
+
-
+
|
diff --git a/lib/Base.php b/lib/Base.php
index 1e686791..8e2343c0 100644
--- a/lib/Base.php
+++ b/lib/Base.php
@@ -39,6 +39,7 @@ define('CONFIG_PATH', APP_PATH . DIRECTORY_SEPARATOR . 'config');
// Setup config files
define('CONFIG_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'config.xml');
define('ACTIONS_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'actions.xml');
+define('MIMETYPES_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'mime.xml');
define('OLD_CONFIG_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'config.php');
define('LOG_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . 'syspass.log');
define('LOCK_FILE', CONFIG_PATH . DIRECTORY_SEPARATOR . '.lock');
diff --git a/lib/Definitions.php b/lib/Definitions.php
index 908d0950..8c37052a 100644
--- a/lib/Definitions.php
+++ b/lib/Definitions.php
@@ -30,6 +30,7 @@ use SP\Config\ConfigData;
use SP\Core\Acl\Acl;
use SP\Core\Acl\Actions;
use SP\Core\Context\ContextInterface;
+use SP\Core\MimeTypes;
use SP\Core\UI\Theme;
use SP\Core\UI\ThemeInterface;
use SP\Http\Request;
@@ -64,6 +65,9 @@ return [
Actions::class => function (ContainerInterface $c) {
return new Actions($c->get(FileCache::class), new XmlHandler(new FileHandler(ACTIONS_FILE)));
},
+ MimeTypes::class => function (ContainerInterface $c) {
+ return new MimeTypes($c->get(FileCache::class), new XmlHandler(new FileHandler(MIMETYPES_FILE)));
+ },
Acl::class => \DI\autowire(Acl::class)
->constructorParameter('action', get(Actions::class)),
ThemeInterface::class => \DI\autowire(Theme::class)
diff --git a/lib/SP/Config/ConfigData.php b/lib/SP/Config/ConfigData.php
index 90a33d96..994b5afc 100644
--- a/lib/SP/Config/ConfigData.php
+++ b/lib/SP/Config/ConfigData.php
@@ -156,7 +156,11 @@ final class ConfigData implements JsonSerializable
/**
* @var array
*/
- private $filesAllowedExts = ['PDF', 'JPG', 'GIF', 'PNG', 'ODT', 'ODS', 'DOC', 'DOCX', 'XLS', 'XSL', 'VSD', 'TXT', 'CSV', 'BAK'];
+ private $filesAllowedExts = [];
+ /**
+ * @var array
+ */
+ private $filesAllowedMime = [];
/**
* @var int
*/
@@ -1073,18 +1077,6 @@ final class ConfigData implements JsonSerializable
return (array)$this->filesAllowedExts;
}
- /**
- * @param array $filesAllowedExts
- *
- * @return $this
- */
- public function setFilesAllowedExts(array $filesAllowedExts = [])
- {
- $this->filesAllowedExts = $filesAllowedExts;
-
- return $this;
- }
-
/**
* @return int
*/
@@ -2141,4 +2133,20 @@ final class ConfigData implements JsonSerializable
{
$this->ldapTlsEnabled = (int)$ldapTlsEnabled;
}
+
+ /**
+ * @return array
+ */
+ public function getFilesAllowedMime(): array
+ {
+ return $this->filesAllowedMime;
+ }
+
+ /**
+ * @param array $filesAllowedMime
+ */
+ public function setFilesAllowedMime(array $filesAllowedMime)
+ {
+ $this->filesAllowedMime = $filesAllowedMime;
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Core/MimeTypes.php b/lib/SP/Core/MimeTypes.php
new file mode 100644
index 00000000..dfcdf3e4
--- /dev/null
+++ b/lib/SP/Core/MimeTypes.php
@@ -0,0 +1,171 @@
+.
+ */
+
+namespace SP\Core;
+
+use SP\Storage\File\FileException;
+use SP\Storage\File\FileStorageInterface;
+use SP\Storage\File\XmlFileStorageInterface;
+
+/**
+ * Class Mime
+ *
+ * @package SP\Core
+ */
+final class MimeTypes
+{
+ /**
+ * Cache file name
+ */
+ const MIME_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'mime.cache';
+ /**
+ * Cache expire time
+ */
+ const CACHE_EXPIRE = 86400;
+ /**
+ * @var int
+ */
+ protected $lastLoadTime;
+ /**
+ * @var array
+ */
+ protected $mimeTypes;
+ /**
+ * @var XmlFileStorageInterface
+ */
+ protected $xmlFileStorage;
+ /**
+ * @var FileStorageInterface
+ */
+ private $fileStorage;
+
+ /**
+ * Mime constructor.
+ *
+ * @param FileStorageInterface $fileStorage
+ * @param XmlFileStorageInterface $xmlFileStorage
+ *
+ * @throws FileException
+ */
+ public function __construct(FileStorageInterface $fileStorage, XmlFileStorageInterface $xmlFileStorage)
+ {
+ $this->xmlFileStorage = $xmlFileStorage;
+ $this->fileStorage = $fileStorage;
+
+ $this->loadCache();
+ }
+
+ /**
+ * Loads MIME types from cache file
+ *
+ * @return void
+ * @throws FileException
+ */
+ protected function loadCache()
+ {
+ try {
+ if ($this->fileStorage->isExpired(self::MIME_CACHE_FILE, self::CACHE_EXPIRE)
+ || $this->fileStorage->isExpiredDate(self::MIME_CACHE_FILE, $this->xmlFileStorage->getFileHandler()->getFileTime())
+ ) {
+ $this->mapAndSave();
+ } else {
+ $this->mimeTypes = $this->fileStorage->load(self::MIME_CACHE_FILE);
+
+ logger('Loaded MIME types cache', 'INFO');
+ }
+ } catch (FileException $e) {
+ processException($e);
+
+ $this->mapAndSave();
+ }
+ }
+
+ /**
+ * @throws FileException
+ */
+ protected function mapAndSave()
+ {
+ logger('MIME TYPES CACHE MISS', 'INFO');
+
+ $this->map();
+ $this->saveCache();
+ }
+
+ /**
+ * Sets an array of mime types
+ *
+ * @throws FileException
+ */
+ protected function map()
+ {
+ $this->mimeTypes = [];
+
+ foreach ($this->load() as $item) {
+ $this->mimeTypes[] = $item;
+ }
+ }
+
+ /**
+ * Loads MIME types from XML
+ *
+ * @return array
+ * @throws FileException
+ */
+ protected function load()
+ {
+ return $this->xmlFileStorage->load('mimetypes')->getItems();
+ }
+
+ /**
+ * Saves MIME types into cache file
+ */
+ protected function saveCache()
+ {
+ try {
+ $this->fileStorage->save(self::MIME_CACHE_FILE, $this->mimeTypes);
+
+ logger('Saved MIME types cache', 'INFO');
+ } catch (FileException $e) {
+ processException($e);
+ }
+ }
+
+ /**
+ * @throws FileException
+ */
+ public function reset()
+ {
+ @unlink(self::MIME_CACHE_FILE);
+
+ $this->loadCache();
+ }
+
+ /**
+ * @return array
+ */
+ public function getMimeTypes(): array
+ {
+ return $this->mimeTypes;
+ }
+}
\ No newline at end of file
diff --git a/lib/SP/Mvc/View/Components/SelectItemAdapter.php b/lib/SP/Mvc/View/Components/SelectItemAdapter.php
index c802508f..4dc41a60 100644
--- a/lib/SP/Mvc/View/Components/SelectItemAdapter.php
+++ b/lib/SP/Mvc/View/Components/SelectItemAdapter.php
@@ -176,9 +176,9 @@ final class SelectItemAdapter implements ItemAdapterInterface
$items = $this->getItemsFromArray();
foreach ($items as $item) {
- if (($useValueAsKey === false && in_array($item->getId(), $selected, false))
- || ($useValueAsKey === true && in_array($item->getName(), $selected, false))
- ) {
+ $value = $useValueAsKey ? $item->getName() : $item->getId();
+
+ if (in_array($value, $selected, false)) {
$item->setSelected(true);
}
}
diff --git a/lib/SP/Providers/Log/DatabaseLogHandler.php b/lib/SP/Providers/Log/DatabaseLogHandler.php
index 2faebe03..6fd69b76 100644
--- a/lib/SP/Providers/Log/DatabaseLogHandler.php
+++ b/lib/SP/Providers/Log/DatabaseLogHandler.php
@@ -27,6 +27,7 @@ namespace SP\Providers\Log;
use DI\Container;
use SP\Core\Events\Event;
use SP\Core\Events\EventReceiver;
+use SP\Core\Exceptions\SPException;
use SP\Core\Language;
use SP\DataModel\EventlogData;
use SP\Providers\EventsTrait;
@@ -90,10 +91,14 @@ final class DatabaseLogHandler extends Provider implements EventReceiver
$eventlogData->setAction($eventType);
$eventlogData->setLevel('INFO');
- if (($e = $event->getSource()) instanceof \Exception) {
- /** @var \Exception $e */
+ $source = $event->getSource();
+
+ if ($source instanceof SPException) {
$eventlogData->setLevel('ERROR');
- $eventlogData->setDescription(__($e->getMessage()));
+ $eventlogData->setDescription(__($source->getMessage()) . PHP_EOL . __($source->getHint()));
+ } elseif ($source instanceof \Exception) {
+ $eventlogData->setLevel('ERROR');
+ $eventlogData->setDescription(__($source->getMessage()));
} elseif (($eventMessage = $event->getEventMessage()) !== null) {
$eventlogData->setDescription($eventMessage->composeText());
}
diff --git a/lib/SP/Services/Export/XmlVerifyService.php b/lib/SP/Services/Export/XmlVerifyService.php
index db95de16..6374e9df 100644
--- a/lib/SP/Services/Export/XmlVerifyService.php
+++ b/lib/SP/Services/Export/XmlVerifyService.php
@@ -123,10 +123,14 @@ final class XmlVerifyService extends Service
public static function checkXmlHash(DOMDocument $document, string $key)
{
$DOMXPath = new DOMXPath($document);
- $hash = $DOMXPath->query('/Root/Meta/Hash')->item(0)->nodeValue;
- $hmac = $DOMXPath->query('/Root/Meta/Hash/@sign')->item(0)->nodeValue;
+ $hash = $DOMXPath->query('/Root/Meta/Hash');
+ $sign = $DOMXPath->query('/Root/Meta/Hash/@sign');
- return Hash::checkMessage($hash, $key, $hmac) || $hash === XmlExportService::generateHashFromNodes($document);
+ if ($hash->length === 1 && $sign->length === 1) {
+ return Hash::checkMessage($hash->item(0)->nodeValue, $key, $sign->item(0)->nodeValue);
+ }
+
+ return $hash === XmlExportService::generateHashFromNodes($document);
}
/**
diff --git a/lib/SP/Services/Import/FileImport.php b/lib/SP/Services/Import/FileImport.php
index 6f8c1e2c..265eb0d3 100644
--- a/lib/SP/Services/Import/FileImport.php
+++ b/lib/SP/Services/Import/FileImport.php
@@ -24,6 +24,7 @@
namespace SP\Services\Import;
+use SP\Core\Exceptions\SPException;
use SP\Http\Request;
use SP\Storage\File\FileException;
use SP\Storage\File\FileHandler;
@@ -59,31 +60,25 @@ final class FileImport
*
* @return FileImport
* @throws FileException
+ * @throws SPException
*/
public static function fromRequest(string $filename, Request $request)
{
- if (($file = $request->getFile($filename)) === null) {
- throw new FileException(
- __u('File successfully uploaded'),
- FileException::ERROR,
- __u('Please check the web server user permissions')
- );
- }
-
- return new self(new FileHandler(self::checkFile($file)));
+ return new self(self::checkFile($request->getFile($filename)));
}
/**
* Leer los datos del archivo.
*
- * @param array $fileData con los datos del archivo
+ * @param array $file con los datos del archivo
*
- * @return string
- * @throws \SP\Storage\File\FileException
+ * @return FileHandler
+ * @throws FileException
+ * @throws SPException
*/
- private static function checkFile($fileData): string
+ private static function checkFile($file): FileHandler
{
- if (!is_array($fileData)) {
+ if (!is_array($file)) {
throw new FileException(
__u('File successfully uploaded'),
FileException::ERROR,
@@ -91,35 +86,30 @@ final class FileImport
);
}
- if ($fileData['name']) {
- // Comprobamos la extensión del archivo
- $fileExtension = mb_strtoupper(pathinfo($fileData['name'], PATHINFO_EXTENSION));
+ try {
+ $fileHandler = new FileHandler($file['tmp_name']);
+ $fileHandler->checkFileExists();
- if ($fileExtension !== 'CSV' && $fileExtension !== 'XML') {
- throw new FileException(
+ if (!in_array($fileHandler->getFileType(), ImportService::ALLOWED_MIME)) {
+ throw new ImportException(
__u('File type not allowed'),
- FileException::ERROR,
- __u('Please, check the file extension')
+ ImportException::ERROR,
+ sprintf(__('MIME type: %s'), $fileHandler->getFileType())
);
}
- }
- // Variables con información del archivo
-// $this->tmpFile = $fileData['tmp_name'];
-// $this->fileType = strtolower($fileData['type']);
-
- if (!file_exists($fileData['tmp_name']) || !is_readable($fileData['tmp_name'])) {
- // Registramos el máximo tamaño permitido por PHP
+ return $fileHandler;
+ } catch (FileException $e) {
logger('Max. upload size: ' . Util::getMaxUpload());
throw new FileException(
__u('Internal error while reading the file'),
FileException::ERROR,
- __u('Please, check PHP configuration for upload files')
+ __u('Please, check PHP configuration for upload files'),
+ $e->getCode(),
+ $e
);
}
-
- return $fileData['tmp_name'];
}
/**
diff --git a/lib/SP/Services/Import/ImportService.php b/lib/SP/Services/Import/ImportService.php
index 4efd2cd3..1a517eec 100644
--- a/lib/SP/Services/Import/ImportService.php
+++ b/lib/SP/Services/Import/ImportService.php
@@ -34,7 +34,7 @@ defined('APP_ROOT') || die();
*/
final class ImportService extends Service
{
- const ALLOWED_EXTS = ['CSV', 'XML'];
+ const ALLOWED_MIME = ['text/csv', 'application/xml', 'text/xml'];
/**
* @var ImportParams
diff --git a/lib/SP/Services/Install/Installer.php b/lib/SP/Services/Install/Installer.php
index c0ac0e7a..d57573d7 100644
--- a/lib/SP/Services/Install/Installer.php
+++ b/lib/SP/Services/Install/Installer.php
@@ -57,7 +57,7 @@ final class Installer extends Service
*/
const VERSION = [3, 0, 0];
const VERSION_TEXT = '3.0-beta';
- const BUILD = 18110601;
+ const BUILD = 18111001;
/**
* @var DatabaseSetupInterface
diff --git a/lib/SP/Services/Upgrade/UpgradeConfigService.php b/lib/SP/Services/Upgrade/UpgradeConfigService.php
index 97f0d6cf..c2925841 100644
--- a/lib/SP/Services/Upgrade/UpgradeConfigService.php
+++ b/lib/SP/Services/Upgrade/UpgradeConfigService.php
@@ -27,6 +27,7 @@ namespace SP\Services\Upgrade;
use SP\Config\ConfigData;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
+use SP\Core\MimeTypes;
use SP\Services\Service;
use SP\Util\VersionUtil;
@@ -40,7 +41,7 @@ final class UpgradeConfigService extends Service implements UpgradeInterface
/**
* @var array Versiones actualizables
*/
- const UPGRADES = ['112.4', '130.16020501', '200.17011202'];
+ const UPGRADES = ['112.4', '130.16020501', '200.17011202', '300.18111001'];
/**
* @var ConfigData
*/
@@ -226,17 +227,83 @@ final class UpgradeConfigService extends Service implements UpgradeInterface
{
switch ($version) {
case '200.17011202':
- $this->configData->setSiteTheme('material-blue');
- $this->configData->setConfigVersion($version);
-
- $this->config->saveConfig($this->configData, false);
-
- $this->eventDispatcher->notifyEvent('upgrade.config.process',
- new Event($this, EventMessage::factory()
- ->addDescription(__u('Update Configuration'))
- ->addDetail(__u('Version'), $version))
- );
+ $this->upgrade_200_17011202($version);
+ break;
+ case '300.18111001':
+ $this->upgrade_300_18111001($version);
break;
}
}
+
+ /**
+ * @param $version
+ *
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
+ * @throws \SP\Storage\File\FileException
+ */
+ private function upgrade_200_17011202($version)
+ {
+ $this->configData->setSiteTheme('material-blue');
+ $this->configData->setConfigVersion($version);
+
+ $this->config->saveConfig($this->configData, false);
+
+ $this->eventDispatcher->notifyEvent('upgrade.config.process',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Update Configuration'))
+ ->addDetail(__u('Version'), $version))
+ );
+ }
+
+ /**
+ * @param $version
+ *
+ * @throws \DI\DependencyException
+ * @throws \DI\NotFoundException
+ * @throws \SP\Storage\File\FileException
+ */
+ private function upgrade_300_18111001($version)
+ {
+ $extensions = array_map('strtolower', $this->configData->getFilesAllowedExts());
+ $mimeTypes = $this->dic->get(MimeTypes::class)->getMimeTypes();
+ $configMimeTypes = [];
+
+ foreach ($extensions as $extension) {
+ $exists = false;
+
+ foreach ($mimeTypes as $mimeType) {
+ if (strtolower($mimeType['extension']) === $extension) {
+ $configMimeTypes[] = $mimeType['type'];
+ $exists = true;
+
+ $this->eventDispatcher->notifyEvent('upgrade.config.process',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('MIME type set for this extension'))
+ ->addDetail(__u('MIME type'), $mimeType['type'])
+ ->addDetail(__u('Extension'), $extension))
+ );
+ }
+ }
+
+ if (!$exists) {
+ $this->eventDispatcher->notifyEvent('upgrade.config.process',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('MIME type not found for this extension'))
+ ->addDetail(__u('Extension'), $extension))
+ );
+ }
+ }
+
+ $this->configData->setFilesAllowedMime($configMimeTypes);
+ $this->configData->setConfigVersion($version);
+
+ $this->config->saveConfig($this->configData, false);
+
+ $this->eventDispatcher->notifyEvent('upgrade.config.process',
+ new Event($this, EventMessage::factory()
+ ->addDescription(__u('Update Configuration'))
+ ->addDetail(__u('Version'), $version))
+ );
+ }
}
\ No newline at end of file
diff --git a/lib/SP/Util/FileUtil.php b/lib/SP/Util/FileUtil.php
index 7e767d27..70d14c4f 100644
--- a/lib/SP/Util/FileUtil.php
+++ b/lib/SP/Util/FileUtil.php
@@ -37,7 +37,7 @@ use SP\DataModel\FileData;
*/
final class FileUtil
{
- const IMAGE_EXTENSIONS = ['JPG', 'PNG', 'GIF'];
+ const IMAGE_MIME = ['image/jpeg', 'image/png', 'image/bmp', 'image/gif'];
/**
* Removes a directory in a recursive way
@@ -71,6 +71,6 @@ final class FileUtil
*/
public static function isImage(FileData $fileData)
{
- return in_array(mb_strtoupper($fileData->getExtension()), self::IMAGE_EXTENSIONS, true);
+ return in_array(strtolower($fileData->getType()), self::IMAGE_MIME, true);
}
}
\ No newline at end of file
diff --git a/public/js/app-actions.js b/public/js/app-actions.js
index b9f9ccb5..7dfd3c41 100644
--- a/public/js/app-actions.js
+++ b/public/js/app-actions.js
@@ -929,7 +929,7 @@ sysPass.Actions = function (log) {
sk: sysPassApp.sk.get()
});
- if (fileType === 'PDF' || fileType === 'application/pdf') {
+ if (fileType === 'application/pdf') {
window.open(url, '_blank');
return;
}
@@ -1551,6 +1551,7 @@ sysPass.Actions = function (log) {
const opts = sysPassApp.requests.getRequestOpts();
opts.method = "get";
+ opts.useLoading = false;
opts.url = sysPassApp.util.getUrl(ajaxUrl.entrypoint,
{
r: "items/notifications",
diff --git a/public/js/app-actions.min.js b/public/js/app-actions.min.js
index 8d8fb3b9..9074bc58 100644
--- a/public/js/app-actions.min.js
+++ b/public/js/app-actions.min.js
@@ -28,13 +28,13 @@ b.data={items:d},sysPassApp.requests.getActionCall(b,function(b){if(0!==b.status
sk:sysPassApp.sk.get(),isAjax:1});d.data={items:b};sysPassApp.requests.getActionCall(d,function(a){sysPassApp.msg.out(a);f({r:g.state.tab.route,tabIndex:g.state.tab.index})})})},save:function(a){c.info("appMgmt:save");g.save(a,function(){q()})},search:function(a){c.info("appMgmt:search");l.search(a)},nav:function(a){c.info("appMgmt:nav");l.nav(a)}},r={check:function(a){c.info("notification:check");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){0===b.status&&f({r:a.data("action-next")});r.getActive()})},search:function(a){c.info("notification:search");l.search(a)},show:function(a){c.info("notification:show");u.show(a)},save:function(a){c.info("notification: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&&($.magnificPopup.close(),f({r:a.data("action-next")}).then(function(){r.getActive()}))})},delete:function(a){c.info("notification: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);f({r:a.data("action-next")}).then(function(){r.getActive()})})})},
-getActive:function(){c.info("notification:getActive");var a=sysPassApp.requests.getRequestOpts();a.method="get";a.url=sysPassApp.util.getUrl(e.entrypoint,{r:"items/notifications",sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(a,function(a){var b=$(".notifications-badge"),c=$(".notifications-tooltip");b.each(function(){var b=$(this);b.attr("data-badge",a.data.count);0===a.data.count?(b.removeClass(b.data("color-class")),c.empty().html(a.data.message)):(b.addClass(b.data("color-class")),
+getActive:function(){c.info("notification:getActive");var a=sysPassApp.requests.getRequestOpts();a.method="get";a.useLoading=!1;a.url=sysPassApp.util.getUrl(e.entrypoint,{r:"items/notifications",sk:sysPassApp.sk.get(),isAjax:1});sysPassApp.requests.getActionCall(a,function(a){var b=$(".notifications-badge"),c=$(".notifications-tooltip");b.each(function(){var b=$(this);b.attr("data-badge",a.data.count);0===a.data.count?(b.removeClass(b.data("color-class")),c.empty().html(a.data.message)):(b.addClass(b.data("color-class")),
c.empty().html(a.data.message_has))});0",c=l.getSelection(a);!1!==c&&mdlDialog().show({text:d,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(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}},v=function(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/runTask",a]});return sysPassApp.requests.getActionEvent(d,function(a){a=a.task+" - "+a.message+" - "+a.time+" - "+a.progress+"%";a+="
"+sysPassApp.config.LANG[62];b.empty().html(a)})};return{getContent:f,showFloatingBox:h,closeFloatingBox:q,appMgmt:u,account:n,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);p(a,b.data.html)})},download:function(a){c.info("file:download");var b=a.data("item-type");a=sysPassApp.util.getUrl(e.entrypoint,{r:[a.data("action-route"),a.data("item-id")],sk:sysPassApp.sk.get()});"PDF"===b||"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]+
+b.status)return sysPassApp.msg.out(b);p(a,b.data.html)})},download:function(a){c.info("file:download");var b=a.data("item-type");a=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&&n.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){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){var d;(b=a.find("input[name='taskId']").val())&&(d=v(b));var c=sysPassApp.requests.getRequestOpts();c.url=e.entrypoint;c.useFullLoading=!!b;c.data=a.serialize();sysPassApp.requests.getActionCall(c,function(b){sysPassApp.msg.out(b);a.find(":input[type=password]").val("");
diff --git a/public/js/app-config.js b/public/js/app-config.js
index 845c78cd..70b576cb 100644
--- a/public/js/app-config.js
+++ b/public/js/app-config.js
@@ -37,8 +37,8 @@ sysPass.Config = function () {
},
FILES: {
MAX_SIZE: 1024, // Max uploading file fize
- ACCOUNT_ALLOWED_EXTS: [], // Allowed extensions for accounts' file uploading
- IMPORT_ALLOWED_EXTS: [] // Allowed extensions for importing
+ ACCOUNT_ALLOWED_MIME: [], // Allowed mime types for accounts' file uploading
+ IMPORT_ALLOWED_MIME: [] // Allowed extensions for importing
},
STATUS: {
CHECK_UPDATES: false, // Check for updates
@@ -83,11 +83,11 @@ sysPass.Config = function () {
setFileMaxSize: function (size) {
config.FILES.MAX_SIZE = parseInt(size);
},
- setFileAccountAllowedExts: function (extensions) {
- config.FILES.ACCOUNT_ALLOWED_EXTS = extensions;
+ setFileAccountAllowedMime: function (mimetypes) {
+ config.FILES.ACCOUNT_ALLOWED_MIME = mimetypes;
},
- setFileImportAllowedExts: function (extensions) {
- config.FILES.IMPORT_ALLOWED_EXTS = extensions;
+ setFileImportAllowedMime: function (mimetypes) {
+ config.FILES.IMPORT_ALLOWED_MIME = mimetypes;
},
setCheckUpdates: function (bool) {
config.STATUS.CHECK_UPDATES = bool;
diff --git a/public/js/app-config.min.js b/public/js/app-config.min.js
index afa1bba6..fb57dda7 100644
--- a/public/js/app-config.min.js
+++ b/public/js/app-config.min.js
@@ -1,3 +1,3 @@
-sysPass.Config=function(){var b={APP_ROOT:"",LANG:[],PKI:{AVAILABLE:!1,KEY:"",MAX_SIZE:0,CRYPTO:null},FILES:{MAX_SIZE:1024,ACCOUNT_ALLOWED_EXTS:[],IMPORT_ALLOWED_EXTS:[]},STATUS:{CHECK_UPDATES:!1,CHECK_NOTICES:!1,CHECK_NOTIFICATIONS:!1},BROWSER:{TIMEZONE:"UTC",LOCALE:"en_US",COOKIES_ENABLED:!1},DEBUG:!0,PLUGINS:[],AUTH:{LOGGEDIN:!1,AUTHBASIC_AUTOLOGIN:!1},SESSION_TIMEOUT:0};return{setAppRoot:function(a){b.APP_ROOT=a},setLang:function(a){b.LANG=a},setSessionTimeout:function(a){b.SESSION_TIMEOUT=parseInt(a)},
-setPkiKey:function(a){0
"+a.messages.join("
"));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'Oops...
'+b.config.LANG[1]+"
"+a+"
"}}};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.setFileAccountAllowedExts(a.data.files_allowed_exts),c.setFileImportAllowedExts(a.data.import_allowed_exts),c.setCookiesEnabled(a.data.cookies_enabled),c.setPlugins(a.data.plugins),c.setLoggedIn(a.data.loggedin),c.setAuthBasicAutologinEnabled(a.data.authbasic_autologin),c.initialize(),
+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
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 0) {
const upload = sysPassApp.util.fileUpload($dropFiles);
- upload.url = sysPassApp.actions.ajaxUrl.entrypoint + "?r=" + $dropFiles.data("action-route");
- upload.allowedExts = sysPassApp.config.FILES.IMPORT_ALLOWED_EXTS;
+ upload.url = sysPassApp.util.getUrl(
+ sysPassApp.actions.ajaxUrl.entrypoint,
+ {r: $dropFiles.data("action-route")}
+ );
+ upload.allowedMime = sysPassApp.config.FILES.IMPORT_ALLOWED_MIME;
upload.beforeSendAction = function () {
upload.setRequestData({
sk: sysPassApp.sk.get(),
@@ -425,9 +428,11 @@ sysPass.Triggers = function (log) {
if ($dropFiles.length > 0) {
const upload = sysPassApp.util.fileUpload($dropFiles);
- upload.url = sysPassApp.actions.ajaxUrl.entrypoint + "?r=" + $dropFiles.data("action-route") + "/" + $dropFiles.data("item-id");
- upload.allowedExts = sysPassApp.config.FILES.ACCOUNT_ALLOWED_EXTS;
-
+ upload.url = sysPassApp.util.getUrl(
+ sysPassApp.actions.ajaxUrl.entrypoint,
+ {r: [$dropFiles.data("action-route"), $dropFiles.data("item-id")]}
+ );
+ upload.allowedMime = sysPassApp.config.FILES.ACCOUNT_ALLOWED_MIME;
upload.requestDoneAction = function () {
sysPassApp.actions.account.listFiles($listFiles);
};
diff --git a/public/js/app-triggers.min.js b/public/js/app-triggers.min.js
index e5913cdf..32052606 100644
--- a/public/js/app-triggers.min.js
+++ b/public/js/app-triggers.min.js
@@ -7,13 +7,13 @@ plugins:["remove_button"]})},d={main:function(a){b.info("views:main");clipboard.
"search");else{a=$("#content");var c=a.data("page");d.common(a);if(""!==c&&"function"===typeof d[c])d[c]()}!0===sysPassApp.config.STATUS.CHECK_UPDATES&&sysPassApp.actions.main.getUpdates();!0===sysPassApp.config.STATUS.CHECK_NOTICES&&sysPassApp.actions.main.getNotices();"function"===typeof sysPassApp.theme.viewsTriggers.main&&sysPassApp.theme.viewsTriggers.main()},search:function(){b.info("views:search");var a=$("#frmSearch");0!==a.length&&(a.find("input[name='search']").on("keyup",function(c){c.preventDefault();
13!==c.which&&13!==c.keyCode||a.submit()}),a.find("select, #rpp").on("change",function(){a.submit()}),a.find("button.btn-clear").on("click",function(c){c.preventDefault();a.find('input[name="searchfav"]').val(0);a[0].reset()}),$("#globalSearch").click(function(){var c=1==$(this).prop("checked")?1:0;a.find("input[name='gsearch']").val(c);a.submit()}),"function"===typeof sysPassApp.theme.viewsTriggers.search&&sysPassApp.theme.viewsTriggers.search())},login:function(){b.info("views:login");var a=$("#frmLogin");
sysPassApp.config.AUTH.AUTHBASIC_AUTOLOGIN&&"0"===a.find("input[name='loggedOut']").val()&&(b.info("views:login:autologin"),sysPassApp.msg.info(sysPassApp.config.LANG[66]),sysPassApp.actions.main.login(a))},userpassreset:function(){b.info("views:userpassreset");var a=$("#frmUserPassReset");sysPassApp.theme.passwordDetect(a)},footer:function(){b.info("views:footer")},common:function(a){b.info("views:common");e(a);var c=a.find(":input[name='sk']");0form").each(function(){var a=$(this);a.find("button.btn-clear").on("click",function(c){c.preventDefault();a.trigger("reset")})})},config:function(){b.info("views:config");var a=$("#drop-import-files");if(0form").each(function(){var a=$(this);a.find("button.btn-clear").on("click",function(c){c.preventDefault();a.trigger("reset")})})},config:function(){b.info("views:config");var a=$("#drop-import-files");if(0 sysPassApp.config.FILES.MAX_SIZE);
};
- const checkFileExtension = function (name) {
- for (let ext in options.allowedExts) {
- if (name.indexOf(options.allowedExts[ext]) !== -1) {
+ const checkFileMimeType = function (mimeType) {
+ if (mimeType === '') {
+ return true;
+ }
+
+ for (let mime in options.allowedMime) {
+ if (mimeType.indexOf(options.allowedMime[mime]) !== -1) {
return true;
}
}
@@ -264,10 +268,11 @@ sysPass.Util = function (log) {
for (let i = 0; i < filesArray.length; i++) {
const file = filesArray[i];
+
if (checkFileSize(file.size)) {
sysPassApp.msg.error(sysPassApp.config.LANG[18] + "
" + file.name + " (Max: " + sysPassApp.config.FILES.MAX_SIZE + ")");
- } else if (!checkFileExtension(file.name.toUpperCase())) {
- sysPassApp.msg.error(sysPassApp.config.LANG[19] + "
" + file.name);
+ } else if (!checkFileMimeType(file.type)) {
+ sysPassApp.msg.error(sysPassApp.config.LANG[19] + "
" + file.type);
} else {
sendFile(filesArray[i]);
}
diff --git a/tests/SP/Services/Account/AccountFileServiceTest.php b/tests/SP/Services/Account/AccountFileServiceTest.php
index 4ecdd208..c486c363 100644
--- a/tests/SP/Services/Account/AccountFileServiceTest.php
+++ b/tests/SP/Services/Account/AccountFileServiceTest.php
@@ -2,8 +2,8 @@
/**
* sysPass
*
- * @author nuxsmin
- * @link https://syspass.org
+ * @author nuxsmin
+ * @link https://syspass.org
* @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
@@ -98,9 +98,9 @@ class AccountFileServiceTest extends DatabaseTestCase
$data = new FileData();
$data->setAccountId(2);
- $data->setName('app.png');
- $data->setType('image/png');
- $data->setExtension('SVG');
+ $data->setName('aaa.txt');
+ $data->setType('text/plain');
+ $data->setExtension('txt');
$data->setContent('');
$data->setSize(0);
@@ -118,7 +118,15 @@ class AccountFileServiceTest extends DatabaseTestCase
$this->assertEquals('no_thumb', $resultData->getThumb());
$this->assertEquals(5, $this->conn->getRowCount('AccountFile'));
+ }
+ /**
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testCreateInvalid()
+ {
$this->expectException(InvalidImageException::class);
$data = new FileData();
diff --git a/tests/res/config/config.xml b/tests/res/config/config.xml
index a14c29cb..b6dfa39a 100644
--- a/tests/res/config/config.xml
+++ b/tests/res/config/config.xml
@@ -9,11 +9,11 @@
1
1
- 5185a5ba55cadceb1968623709dddb1d7626ed44
+ 9ae12959c88b80ce06b7a4637bd0375ea6f9d1da
0
0
- 1541544393
- f292660712a4970a14bb85c93d08c5611d8077a4
+ 1541881367
+ 481481df4e0c5d89f6cd01bffe151a6c8ba33bd4
@@ -32,7 +32,7 @@
0
- 9d4a01b3e797c5d98f932e13ef6666d2fe5b52e9
+ 54960891f385bc6fe57d75674340e278fa0291fc
- PDF
- JPG
@@ -49,6 +49,7 @@
- CSV
- BAK
+
1024
1
1