diff --git a/app/modules/web/Controllers/ConfigEncryptionController.php b/app/modules/web/Controllers/ConfigEncryptionController.php index b71008e9..0833be1b 100644 --- a/app/modules/web/Controllers/ConfigEncryptionController.php +++ b/app/modules/web/Controllers/ConfigEncryptionController.php @@ -37,7 +37,6 @@ use SP\Services\Crypt\MasterPassService; use SP\Services\Crypt\TemporaryMasterPassService; use SP\Services\Crypt\UpdateMasterPassRequest; use SP\Services\Task\TaskFactory; -use SP\Util\Util; /** * Class ConfigEncryptionController @@ -52,9 +51,9 @@ final class ConfigEncryptionController extends SimpleControllerBase * @return bool * @throws \DI\DependencyException * @throws \DI\NotFoundException - * @throws \SP\Core\Exceptions\SPException * @throws \SP\Repositories\NoSuchItemException * @throws \SP\Services\ServiceException + * @throws \SP\Core\Exceptions\SPException */ public function saveAction() { @@ -70,41 +69,69 @@ final class ConfigEncryptionController extends SimpleControllerBase $taskId = $this->request->analyzeString('taskId'); if (!$mastePassService->checkUserUpdateMPass($this->session->getUserData()->getLastUpdateMPass())) { - return $this->returnJsonResponse(JsonResponse::JSON_SUCCESS_STICKY, __u('Master password updated'), [__u('Please, restart the session for update it')]); + return $this->returnJsonResponse( + JsonResponse::JSON_SUCCESS_STICKY, + __u('Master password updated'), + [__u('Please, restart the session for update it')] + ); } if (empty($newMasterPass) || empty($currentMasterPass)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Master password not entered')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Master password not entered') + ); } if ($confirmPassChange === false) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('The password update must be confirmed')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('The password update must be confirmed') + ); } if ($newMasterPass === $currentMasterPass) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Passwords are the same')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Passwords are the same') + ); } if ($newMasterPass !== $newMasterPassR) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('Master passwords do not match')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('Master passwords do not match') + ); } if (!$mastePassService->checkMasterPassword($currentMasterPass)) { - return $this->returnJsonResponse(JsonResponse::JSON_ERROR, __u('The current master password does not match')); + return $this->returnJsonResponse( + JsonResponse::JSON_ERROR, + __u('The current master password does not match') + ); + } + + if (!$this->config->getConfigData()->isMaintenance()) { + return $this->returnJsonResponse( + JsonResponse::JSON_WARNING, + __u('Maintenance mode not enabled'), + [__u('Please, emable it to avoid unwanted behavior from other sessions')] + ); } if ($this->config->getConfigData()->isDemoEnabled()) { - return $this->returnJsonResponse(JsonResponse::JSON_WARNING, __u('Ey, this is a DEMO!!')); + return $this->returnJsonResponse( + JsonResponse::JSON_WARNING, + __u('Ey, this is a DEMO!!') + ); } $configService = $this->dic->get(ConfigService::class); if (!$noAccountPassChange) { - Util::lockApp($this->session->getUserData()->getId(), 'masterpass'); - - $task = $taskId !== null ? TaskFactory::create(__FUNCTION__, $taskId) : null; - try { + $task = $taskId !== null ? TaskFactory::create(__FUNCTION__, $taskId) : null; + $request = new UpdateMasterPassRequest( $currentMasterPass, $newMasterPass, @@ -124,10 +151,8 @@ final class ConfigEncryptionController extends SimpleControllerBase return $this->returnJsonResponseException($e); } finally { - Util::unlockApp(); - - if ($task) { - TaskFactory::end($task->getTaskId()); + if (isset($task)) { + TaskFactory::end($task); } } } else { @@ -193,12 +218,15 @@ final class ConfigEncryptionController extends SimpleControllerBase $groupId = $this->request->analyzeInt('temporary_masterpass_group', 0); $sendEmail = $this->configData->isMailEnabled() - && $this->request->analyzeBool('temporary_masterpass_email') - && $groupId > 0; + && $this->request->analyzeBool('temporary_masterpass_email'); if ($sendEmail) { try { - $temporaryMasterPassService->sendByEmailForGroup($groupId, $key); + if ($groupId > 0) { + $temporaryMasterPassService->sendByEmailForGroup($groupId, $key); + } else { + $temporaryMasterPassService->sendByEmailForAllUsers($key); + } return $this->returnJsonResponse( JsonResponse::JSON_SUCCESS, diff --git a/app/modules/web/Controllers/ConfigGeneralController.php b/app/modules/web/Controllers/ConfigGeneralController.php index 541f5bab..21f98056 100644 --- a/app/modules/web/Controllers/ConfigGeneralController.php +++ b/app/modules/web/Controllers/ConfigGeneralController.php @@ -34,6 +34,7 @@ use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\ConfigTrait; use SP\Services\Config\ConfigBackupService; use SP\Storage\File\FileHandler; +use SP\Util\Util; /** * Class ConfigGeneral @@ -169,7 +170,11 @@ final class ConfigGeneralController extends SimpleControllerBase return $this->saveConfig( $configData, $this->config, - function () use ($eventMessage) { + function () use ($eventMessage, $configData) { + if ($configData->isMaintenance()) { + Util::lockApp($this->session->getUserData()->getId(), 'config'); + } + $this->eventDispatcher->notifyEvent( 'save.config.general', new Event($this, $eventMessage) diff --git a/app/modules/web/Controllers/ConfigManagerController.php b/app/modules/web/Controllers/ConfigManagerController.php index 9f75ac1c..a0ba3df3 100644 --- a/app/modules/web/Controllers/ConfigManagerController.php +++ b/app/modules/web/Controllers/ConfigManagerController.php @@ -278,7 +278,7 @@ final class ConfigManagerController extends ControllerBase $numAccounts = $this->dic->get(AccountService::class)->getTotalNumAccounts(); $template->assign('numAccounts', $numAccounts); - if ($numAccounts > 500) { + if ($numAccounts > 100) { $template->assign('taskId', Task::genTaskId('masterpass')); } diff --git a/app/modules/web/Controllers/ItemsController.php b/app/modules/web/Controllers/ItemsController.php index bbe53bb0..9e099c4a 100644 --- a/app/modules/web/Controllers/ItemsController.php +++ b/app/modules/web/Controllers/ItemsController.php @@ -117,7 +117,11 @@ final class ItemsController extends SimpleControllerBase $notifications = array_map( function ($notification) { /** @@var $notification NotificationData */ - return sprintf('(%s) - %s', $notification->getComponent(), Html::truncate($notification->getDescription(), 30)); + return sprintf( + '(%s) - %s', + $notification->getComponent(), + Html::truncate(Html::stripTags($notification->getDescription()), 30) + ); }, $this->dic ->get(NotificationService::class) ->getAllActiveForUserId($this->session->getUserData()->getId())); @@ -169,7 +173,7 @@ final class ItemsController extends SimpleControllerBase * * @return array */ - protected function prepareItems(array $items) + private function prepareItems(array $items) { $outItems = []; diff --git a/app/modules/web/Controllers/TaskController.php b/app/modules/web/Controllers/TaskController.php index 6e7d1737..765b9a79 100644 --- a/app/modules/web/Controllers/TaskController.php +++ b/app/modules/web/Controllers/TaskController.php @@ -24,11 +24,9 @@ namespace SP\Modules\Web\Controllers; -use DI\Container; use Klein\Klein; -use SP\Core\Context\SessionContext; +use Psr\Container\ContainerInterface; use SP\Services\ServiceException; -use SP\Services\Task\Task; use SP\Services\Task\TaskFactory; use SP\Services\Task\TaskService; @@ -40,41 +38,46 @@ use SP\Services\Task\TaskService; final class TaskController { /** - * @var Container + * @var TaskService */ - private $container; + private $taskService; + /** + * @var Klein + */ + private $router; /** * TaskController constructor. * - * @param Container $container - * - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface + * @param ContainerInterface $container */ - public function __construct(Container $container) + public function __construct(ContainerInterface $container) { - $this->container = $container; + $this->router = $container->get(Klein::class); + $this->taskService = $container->get(TaskService::class); } /** * @param string $taskId - * - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface */ - public function runTaskAction($taskId) + public function trackStatusAction($taskId) { - SessionContext::close(); + $response = $this->router->response(); + $response->header('Content-Type', 'text/event-stream'); + $response->header('Cache-Control', 'no-store, no-cache'); + $response->header('Access-Control-Allow-Origin', '*'); + $response->send(true); - $router = $this->container->get(Klein::class); - $router->response()->header('Content-Type', 'text/event-stream'); - $router->response()->header('Cache-Control', 'no-store, no-cache'); - $router->response()->header('Access-Control-Allow-Origin', '*'); - $router->response()->send(true); + ob_end_flush(); try { - $this->container->get(TaskService::class)->run($taskId); + $this->taskService->trackStatus($taskId, + function ($id, $message) { + echo 'id: ', $id, PHP_EOL, 'data: ', $message, PHP_EOL, PHP_EOL; + + ob_flush(); + flush(); + }); } catch (ServiceException $e) { processException($e); } @@ -82,13 +85,26 @@ final class TaskController /** * @param $taskId + * + * @throws \SP\Storage\File\FileException */ public function testTaskAction($taskId) { - $task = TaskFactory::create($taskId, Task::genTaskId($taskId)); - - TaskFactory::update($task->getTaskId(), TaskFactory::createMessage($task->getTaskId(), 'Test Task')); + $task = TaskFactory::create($taskId, $taskId); echo $task->getTaskId(); + + $count = 0; + + while ($count < 60) { + TaskFactory::update($task, + TaskFactory::createMessage($task->getTaskId(), "Test Task $count") + ); + + sleep(1); + $count++; + } + + TaskFactory::end($task); } } \ No newline at end of file diff --git a/app/modules/web/Init.php b/app/modules/web/Init.php index 953d707a..5aa3cd16 100644 --- a/app/modules/web/Init.php +++ b/app/modules/web/Init.php @@ -60,7 +60,15 @@ final class Init extends ModuleBase * List of controllers that don't need to perform fully initialization * like: install/database checks, session/event handlers initialization */ - const PARTIAL_INIT = ['resource', 'install', 'bootstrap', 'status', 'upgrade', 'error']; + const PARTIAL_INIT = [ + 'resource', + 'install', + 'bootstrap', + 'status', + 'upgrade', + 'error', + 'task' + ]; /** * List of controllers that don't need to update the user's session activity */ diff --git a/app/modules/web/themes/material-blue/js/app-theme.js b/app/modules/web/themes/material-blue/js/app-theme.js index 5968a4d4..d891a643 100644 --- a/app/modules/web/themes/material-blue/js/app-theme.js +++ b/app/modules/web/themes/material-blue/js/app-theme.js @@ -258,7 +258,7 @@ sysPass.Theme = function (log) { // Crear evento para mostrar clave generada/introducida $icon.on("mouseover", function () { - $icon.attr("title", $this.val()); + $icon.attr("title", $this[0].dataset.pass); }); }); }; diff --git a/app/modules/web/themes/material-blue/js/app-theme.min.js b/app/modules/web/themes/material-blue/js/app-theme.min.js index 67aac5fa..57d6390a 100644 --- a/app/modules/web/themes/material-blue/js/app-theme.min.js +++ b/app/modules/web/themes/material-blue/js/app-theme.min.js @@ -12,10 +12,10 @@ c.attr("id")+"-"+a;var l=b.find("#"+c.attr("id")+"_repeat");l.attr("id",a+"_repe '\n