diff --git a/ProcessMaker/Filters/Filter.php b/ProcessMaker/Filters/Filter.php index 849bf2eccd..4474d888a3 100644 --- a/ProcessMaker/Filters/Filter.php +++ b/ProcessMaker/Filters/Filter.php @@ -6,6 +6,8 @@ use Illuminate\Support\Arr; use ProcessMaker\Models\ProcessRequestToken; use ProcessMaker\Models\User; +use ProcessMaker\Query\BaseField; +use ProcessMaker\Query\Expression; class Filter { @@ -17,6 +19,8 @@ class Filter const TYPE_PROCESS = 'Process'; + const TYPE_RELATIONSHIP = 'Relationship'; + public string|null $subjectValue; public string $subjectType; @@ -63,6 +67,8 @@ private function apply($query) $this->valueAliasAdapter($valueAliasMethod, $query); } elseif ($this->subjectType === self::TYPE_PROCESS) { $this->filterByProcessId($query); + } elseif ($this->subjectType === self::TYPE_RELATIONSHIP) { + $this->filterByRelationship($query); } else { $this->applyQueryBuilderMethod($query); } @@ -103,7 +109,7 @@ private function operator() if ($this->operator === 'regex') { $this->operator = 'REGEXP'; } - + return $this->operator; } @@ -145,9 +151,18 @@ private function subject() return 'process_id'; } + if ($this->subjectType === self::TYPE_RELATIONSHIP) { + return $this->relationshipSubjectTypeParts()[1]; + } + return $this->subjectValue; } + private function relationshipSubjectTypeParts() + { + return explode('.', $this->subjectValue); + } + private function value() { if ($this->operator === 'contains') { @@ -212,6 +227,7 @@ private function convertUserIdsToUsernames($values) { return array_map(function ($value) { $username = User::find($value)?->username; + return isset($username) ? $username : $value; }, $values); } @@ -227,4 +243,12 @@ private function filterByProcessId(Builder $query) $this->applyQueryBuilderMethod($query); } } + + private function filterByRelationship(Builder $query) + { + $relationshipName = $this->relationshipSubjectTypeParts()[0]; + $query->whereHas($relationshipName, function ($rel) { + $this->applyQueryBuilderMethod($rel); + }); + } } diff --git a/ProcessMaker/Filters/SaveSession.php b/ProcessMaker/Filters/SaveSession.php index 7616381b14..77fd973e9b 100644 --- a/ProcessMaker/Filters/SaveSession.php +++ b/ProcessMaker/Filters/SaveSession.php @@ -8,12 +8,12 @@ class SaveSession { /** * Retrieve cached data; this is preserved for a week. - * @param Array $json - * @return Array + * @param array $json + * @return array */ private static function get($key, $json) { - return Cache::remember($key, now()->addWeek(), function () use($json) { + return Cache::remember($key, now()->addWeek(), function () use ($json) { return $json; }); } @@ -26,24 +26,25 @@ private static function get($key, $json) */ private static function getKey($user, $name) { - return str_replace("-", "_", "user-{$user->id}-{$user->uuid}-{$name}"); + return str_replace('-', '_', "user-{$user->id}-{$user->uuid}-{$name}"); } /** * Get filter configuration. - * @param String $name + * @param string $name * @param User $user * @return type */ public static function getConfigFilter(String $name, Object $user) { $key = self::getKey($user, $name); + return self::get($key, []); } /** * Store filter configuration. - * @param String $name + * @param string $name * @param User $user * @param array $array * @return type @@ -52,6 +53,7 @@ public static function setConfigFilter(String $name, Object $user, array $array) { $key = self::getKey($user, $name); Cache::pull($key); + return self::get($key, $array); } -} \ No newline at end of file +} diff --git a/ProcessMaker/Http/Controllers/Api/BookmarkController.php b/ProcessMaker/Http/Controllers/Api/BookmarkController.php index 9df134a651..0ae85b1a78 100644 --- a/ProcessMaker/Http/Controllers/Api/BookmarkController.php +++ b/ProcessMaker/Http/Controllers/Api/BookmarkController.php @@ -46,7 +46,7 @@ public function store(Request $request, Process $process) try { $bookmark->updateOrCreate([ 'process_id' => $process->id, - 'user_id' => Auth::user()->id + 'user_id' => Auth::user()->id, ]); } catch (\Exception $e) { return response()->json(['error' => $e->getMessage()], 400); diff --git a/ProcessMaker/Http/Controllers/Api/ProcessController.php b/ProcessMaker/Http/Controllers/Api/ProcessController.php index f79a9e53d5..1ec1a6269f 100644 --- a/ProcessMaker/Http/Controllers/Api/ProcessController.php +++ b/ProcessMaker/Http/Controllers/Api/ProcessController.php @@ -51,6 +51,7 @@ class ProcessController extends Controller 'bpmn', 'svg', ]; + public $doNotSanitizeMustache = [ 'case_title', ]; @@ -122,6 +123,9 @@ public function index(Request $request) $processes->processCategory($category); } + // Filter by category status + $processes->categoryStatus($request->input('cat_status', null)); + if (!empty($pmql)) { try { $processes->pmql($pmql); @@ -262,10 +266,10 @@ public function startEvents(Request $request, Process $process) $startEvents = []; $currentUser = Auth::user(); foreach ($process->start_events as $event) { - if (count($event["eventDefinitions"]) === 0) { - if (array_key_exists("config", $event)) { - $webEntry = json_decode($event["config"])->web_entry; - $event["webEntry"] = $webEntry; + if (count($event['eventDefinitions']) === 0) { + if (array_key_exists('config', $event)) { + $webEntry = json_decode($event['config'])->web_entry; + $event['webEntry'] = $webEntry; } if ( $this->checkUserCanStartProcess($event, $currentUser->id, $process, $request) || @@ -275,6 +279,7 @@ public function startEvents(Request $request, Process $process) } } } + return new ApiCollection($startEvents); } @@ -466,7 +471,7 @@ public function update(Request $request, Process $process) } } - $this->saveImagesIntoMedia($request, $process); + $this->saveImagesIntoMedia($request, $process); // Catch errors to send more specific status try { $process->saveOrFail(); @@ -1497,6 +1502,7 @@ protected function getRequestFilterBy(Request $request, array $searchableColumns return $where; } + /** * check if currentUser can start the request * @@ -1510,23 +1516,24 @@ protected function getRequestFilterBy(Request $request, array $searchableColumns protected function checkUserCanStartProcess($event, $currentUser, $process, $request) { $response = false; - if (array_key_exists("assignment", $event)) { - switch ($event["assignment"]) { - case "user": - if (array_key_exists("assignedUsers", $event)) { - $response = $currentUser === (int)$event["assignedUsers"]; + if (array_key_exists('assignment', $event)) { + switch ($event['assignment']) { + case 'user': + if (array_key_exists('assignedUsers', $event)) { + $response = $currentUser === (int) $event['assignedUsers']; } break; - case "group": - if (array_key_exists("assignedGroups", $event)) { - $response = $this->checkUsersGroup((int)$event["assignedGroups"], $request); + case 'group': + if (array_key_exists('assignedGroups', $event)) { + $response = $this->checkUsersGroup((int) $event['assignedGroups'], $request); } - break; - case "process_manager": + break; + case 'process_manager': $response = $currentUser === $process->manager_id; - break; + break; } } + return $response; } @@ -1543,24 +1550,24 @@ protected function checkUsersGroup(int $groupId, Request $request) $currentUser = Auth::user()->id; $group = Group::find($groupId); $response = false; - if (isset($group)){ + if (isset($group)) { try { $responseUsers = (new GroupController(new Group()))->users($group, $request); $users = $responseUsers->all(); - + foreach ($users as $user) { - if($user->resource->member_id === $currentUser) { + if ($user->resource->member_id === $currentUser) { $response = true; } } } catch (\Exception $error) { return ['error' => $error->getMessage()]; } - + try { $responseGroups = (new GroupController(new Group()))->groups($group, $request); $groups = $responseGroups->all(); - + foreach ($groups as $group) { if ($this->checkUsersGroup($group->resource->member_id, $request)) { $response = true; @@ -1570,6 +1577,7 @@ protected function checkUsersGroup(int $groupId, Request $request) return ['error' => $error->getMessage()]; } } + return $response; } @@ -1697,7 +1705,7 @@ public function duplicate(Process $process, Request $request) } public function saveImagesIntoMedia(Request $request, Process $process) - { + { // Saving Carousel Images into Media table related to process_id if (is_array($request->imagesCarousel) && !empty($request->imagesCarousel)) { foreach ($request->imagesCarousel as $image) { @@ -1706,19 +1714,22 @@ public function saveImagesIntoMedia(Request $request, Process $process) ->where('uuid', $image['uuid'])->exists()) { $process->addMediaFromBase64($image['url'])->toMediaCollection('images_carousel'); } - } + } } } } - public function getMediaImages(Request $request, Process $process) { + public function getMediaImages(Request $request, Process $process) + { $media = Process::with(['media']) ->where('id', $process->id) ->get(); + return new ProcessCollection($media); } - public function deleteMediaImages(Request $request, Process $process) { + public function deleteMediaImages(Request $request, Process $process) + { $process = Process::find($process->id); // Get UUID image in media table diff --git a/ProcessMaker/Http/Controllers/Api/UserController.php b/ProcessMaker/Http/Controllers/Api/UserController.php index 7dfbd201f4..fac6fc619a 100644 --- a/ProcessMaker/Http/Controllers/Api/UserController.php +++ b/ProcessMaker/Http/Controllers/Api/UserController.php @@ -369,6 +369,7 @@ private function validateCellPhoneNumber(User $user, $number) ], ], 422); } + return false; } diff --git a/ProcessMaker/Http/Controllers/Auth/TwoFactorAuthController.php b/ProcessMaker/Http/Controllers/Auth/TwoFactorAuthController.php index 693b059a3d..ae51455f8b 100644 --- a/ProcessMaker/Http/Controllers/Auth/TwoFactorAuthController.php +++ b/ProcessMaker/Http/Controllers/Auth/TwoFactorAuthController.php @@ -17,8 +17,11 @@ class TwoFactorAuthController extends Controller private $twoFactorAuthentication; const TFA_ERROR = '2fa-error'; + const TFA_MESSAGE = '2fa-message'; + const TFA_AUTH_APP = '2fa-auth-app'; + const TFA_VALIDATED = '2fa-validated'; public function __construct() @@ -173,6 +176,7 @@ private function testEmailServer() 'message' => __('Unable to send email. Please check your email server settings.'), ], 500); } + return true; } @@ -206,6 +210,7 @@ private function testSmsServer() 'message' => __('Unable to send SMS. Please check your cell number and SMS server settings.'), ], 500); } + return true; } } diff --git a/ProcessMaker/Http/Controllers/RequestController.php b/ProcessMaker/Http/Controllers/RequestController.php index c738cdfd79..6f03db4b49 100644 --- a/ProcessMaker/Http/Controllers/RequestController.php +++ b/ProcessMaker/Http/Controllers/RequestController.php @@ -58,8 +58,8 @@ public function index($type = null) ['type', 'title', 'currentUser'] )); } - - $userFilter = SaveSession::getConfigFilter("requestFilter", Auth::user()); + + $userFilter = SaveSession::getConfigFilter('requestFilter', Auth::user()); return view('requests.index', compact( ['type', 'title', 'currentUser', 'userFilter'] diff --git a/ProcessMaker/Http/Controllers/TaskController.php b/ProcessMaker/Http/Controllers/TaskController.php index 41e7616d78..b1f0783def 100644 --- a/ProcessMaker/Http/Controllers/TaskController.php +++ b/ProcessMaker/Http/Controllers/TaskController.php @@ -40,8 +40,8 @@ public function index() if (isset($_SERVER['HTTP_USER_AGENT']) && MobileHelper::isMobile($_SERVER['HTTP_USER_AGENT'])) { return view('tasks.mobile', compact('title')); } - - $userFilter = SaveSession::getConfigFilter("taskFilter", Auth::user()); + + $userFilter = SaveSession::getConfigFilter('taskFilter', Auth::user()); return view('tasks.index', compact('title', 'userFilter')); } diff --git a/ProcessMaker/Http/Middleware/SanitizeInput.php b/ProcessMaker/Http/Middleware/SanitizeInput.php index dc7d204e08..ea39894652 100644 --- a/ProcessMaker/Http/Middleware/SanitizeInput.php +++ b/ProcessMaker/Http/Middleware/SanitizeInput.php @@ -18,6 +18,7 @@ class SanitizeInput extends TransformsRequest public $except = [ // ]; + public $allowExpressions = []; /** diff --git a/ProcessMaker/Http/Middleware/SessionControlBlock.php b/ProcessMaker/Http/Middleware/SessionControlBlock.php index e7a0aa7ea2..e0fd6058d0 100644 --- a/ProcessMaker/Http/Middleware/SessionControlBlock.php +++ b/ProcessMaker/Http/Middleware/SessionControlBlock.php @@ -14,6 +14,7 @@ class SessionControlBlock { const IP_RESTRICTION_KEY = 'session-control.ip_restriction'; + const DEVICE_RESTRICTION_KEY = 'session-control.device_restriction'; /** @@ -42,10 +43,10 @@ public function handle(Request $request, Closure $next): Response private function getUser(Request $request): ?User { - return User::with(['sessions' => function($query) { - $query->where('is_active', true); - }]) - ->whereHas('sessions', function(Builder $query) { + return User::with(['sessions' => function ($query) { + $query->where('is_active', true); + }]) + ->whereHas('sessions', function (Builder $query) { $query->where('is_active', true); })->where('username', $request->input('username')) ->first(); diff --git a/ProcessMaker/Http/Middleware/SessionControlKill.php b/ProcessMaker/Http/Middleware/SessionControlKill.php index 94646bf93a..bcc18be214 100644 --- a/ProcessMaker/Http/Middleware/SessionControlKill.php +++ b/ProcessMaker/Http/Middleware/SessionControlKill.php @@ -15,6 +15,7 @@ class SessionControlKill { const IP_RESTRICTION_KEY = 'session-control.ip_restriction'; + const DEVICE_RESTRICTION_KEY = 'session-control.device_restriction'; /** @@ -52,7 +53,7 @@ private function getActiveSession(User $user, string $userSession): ?UserSession ->where([ ['is_active', true], ['token', $userSession], - ['expired_date', '!=', null] + ['expired_date', '!=', null], ]) ->first(); } @@ -68,6 +69,7 @@ private function getActiveSession(User $user, string $userSession): ?UserSession private function isSessionExpiredByIP(UserSession $session, Request $request): bool { $ip = $request->getClientIp() ?? $request->ip(); + return $session->ip_address === $ip && !is_null($session->expired_date); } diff --git a/ProcessMaker/Jobs/CompileSass.php b/ProcessMaker/Jobs/CompileSass.php index 14e3c7a20d..1333df45d1 100644 --- a/ProcessMaker/Jobs/CompileSass.php +++ b/ProcessMaker/Jobs/CompileSass.php @@ -86,6 +86,8 @@ private function fixPathsInGeneratedAppCss() $file = file_get_contents('public/css/app.css'); $file = preg_replace('/\.\/fonts(\/[A-Za-z]+\/)OpenSans\-/m', '/fonts/OpenSans-', $file); $file = str_replace('public/css/precompiled/vue-multiselect.min.css', 'css/precompiled/vue-multiselect.min.css', $file); + $file = str_replace('public/css/precompiled/poppins/300.css', 'css/precompiled/poppins/300.css', $file); + $file = str_replace('public/css/precompiled/poppins/500.css', 'css/precompiled/poppins/500.css', $file); $file = str_replace('url("../webfonts/', 'url("/fonts/', $file); $file = str_replace('url("../fonts/', 'url("/fonts/', $file); $file = str_replace('url("fonts/', 'url("/fonts/', $file); diff --git a/ProcessMaker/Listeners/SamlAuthenticated.php b/ProcessMaker/Listeners/SamlAuthenticated.php index 84c6d5ff50..c58e112a76 100644 --- a/ProcessMaker/Listeners/SamlAuthenticated.php +++ b/ProcessMaker/Listeners/SamlAuthenticated.php @@ -2,8 +2,8 @@ namespace ProcessMaker\Listeners; -use Illuminate\Auth\Events\Authenticated; use CodeGreenCreative\SamlIdp\Jobs\SamlSso; +use Illuminate\Auth\Events\Authenticated; class SamlAuthenticated { diff --git a/ProcessMaker/Listeners/UserSession.php b/ProcessMaker/Listeners/UserSession.php index b04b04d213..4bbc799f11 100644 --- a/ProcessMaker/Listeners/UserSession.php +++ b/ProcessMaker/Listeners/UserSession.php @@ -3,10 +3,10 @@ namespace ProcessMaker\Listeners; use Illuminate\Database\Eloquent\Builder; -use ProcessMaker\Models\UserSession as Session; use Illuminate\Support\Str; use Jenssegers\Agent\Agent; use ProcessMaker\Models\Setting; +use ProcessMaker\Models\UserSession as Session; class UserSession { diff --git a/ProcessMaker/Managers/ScreenBuilderManager.php b/ProcessMaker/Managers/ScreenBuilderManager.php index 54372b567a..fb4e1d88e2 100644 --- a/ProcessMaker/Managers/ScreenBuilderManager.php +++ b/ProcessMaker/Managers/ScreenBuilderManager.php @@ -59,6 +59,7 @@ public function addPackageScripts($type = 'DISPLAY') $installed = app(PackageManifest::class)->list(); $directories = array_values(array_filter($directories, function ($directory) use ($installed) { $package = 'processmaker/' . basename($directory); + return in_array($package, $installed); })); foreach ($directories as $directory) { diff --git a/ProcessMaker/Models/Process.php b/ProcessMaker/Models/Process.php index 1a4f4d7489..1d08a20d51 100644 --- a/ProcessMaker/Models/Process.php +++ b/ProcessMaker/Models/Process.php @@ -464,6 +464,19 @@ public function scopeProcessCategory($query, int $id) }); } + /** + * Scope a query to include a specific category + * @param string $status + */ + public function scopeCategoryStatus($query, $status) + { + if (!empty($status)) { + return $query->whereHas('categories', function ($query) use ($status) { + $query->where('process_categories.status', $status); + }); + } + } + public function getCollaborations() { $this->bpmnDefinitions = app(BpmnDocumentInterface::class, ['process' => $this]); @@ -1702,8 +1715,10 @@ public function scopeFilter($query, $filterStr) $query->where('processes.name', 'like', $filter) ->orWhere('processes.description', 'like', $filter) ->orWhere('processes.status', '=', $filterStr) - ->orWhere('user.firstname', 'like', $filter) - ->orWhere('user.lastname', 'like', $filter) + ->orWhereHas('user', function ($query) use ($filter) { + $query->where('firstname', 'like', $filter) + ->orWhere('lastname', 'like', $filter); + }) ->orWhereIn('processes.id', function ($qry) use ($filter) { $qry->select('assignable_id') ->from('category_assignments') diff --git a/ProcessMaker/Models/UserSession.php b/ProcessMaker/Models/UserSession.php index 736aea40ad..e9daa7617d 100644 --- a/ProcessMaker/Models/UserSession.php +++ b/ProcessMaker/Models/UserSession.php @@ -65,7 +65,7 @@ public static function expiresDuplicatedSessionByDevice() ->orderBy('id', 'desc') ->chunk(100, function ($sessions) use (&$usersActiveDevice) { foreach ($sessions as $session) { - $key = $session->user_id . '.'. + $key = $session->user_id . '.' . $session->device_name . '.' . $session->device_type . '.' . $session->device_platform; diff --git a/ProcessMaker/Nayra/Managers/WorkflowManagerDefault.php b/ProcessMaker/Nayra/Managers/WorkflowManagerDefault.php index 4902a9ec37..7b19efc608 100644 --- a/ProcessMaker/Nayra/Managers/WorkflowManagerDefault.php +++ b/ProcessMaker/Nayra/Managers/WorkflowManagerDefault.php @@ -272,7 +272,7 @@ public function throwSignalEventDefinition(EventDefinitionInterface $sourceEvent /** * Retrieves IDs of all instances collaborating with the given instance. * - * This function compiles a list of IDs from execution instances associated + * This function compiles a list of IDs from execution instances associated * with the same process as the input instance, including the instance itself. * * @param ProcessRequest $instance The instance to find collaborators for. @@ -285,6 +285,7 @@ protected function getCollaboratingInstanceIds($instance) foreach ($instances as $instance) { $ids[] = $instance->getId(); } + return $ids; } diff --git a/ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php b/ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php index 399df6f94d..83761ca014 100644 --- a/ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php +++ b/ProcessMaker/Nayra/Managers/WorkflowManagerRabbitMq.php @@ -567,6 +567,7 @@ protected function getCollaboratingInstanceIds($instance) where('process_collaboration_id', $instance->process_collaboration_id) ->pluck('id') ->toArray(); + return $ids; } diff --git a/ProcessMaker/Nayra/Repositories/PersistenceTokenTrait.php b/ProcessMaker/Nayra/Repositories/PersistenceTokenTrait.php index 5673528eaf..5a59eb7e62 100644 --- a/ProcessMaker/Nayra/Repositories/PersistenceTokenTrait.php +++ b/ProcessMaker/Nayra/Repositories/PersistenceTokenTrait.php @@ -164,11 +164,13 @@ public function persistGatewayTokenPassed(array $transaction) $gateway = $this->deserializer->unserializeEntity($transaction['gateway']); if (!is_numeric($transaction['transition'])) { Log::info('Invalid transition id for gateway token passed. ' . json_encode($transaction)); + return; } $transition = $gateway->getTransitions()[$transaction['transition']] ?? null; if (empty($transition)) { Log::info('Invalid transition for gateway token passed. ' . json_encode($transaction)); + return; } $tokens = $this->deserializer->unserializeTokensCollection($transaction['tokens']); diff --git a/ProcessMaker/Notifications/TwoFactorAuthNotification.php b/ProcessMaker/Notifications/TwoFactorAuthNotification.php index 1b175d839b..2b36e3953a 100644 --- a/ProcessMaker/Notifications/TwoFactorAuthNotification.php +++ b/ProcessMaker/Notifications/TwoFactorAuthNotification.php @@ -13,6 +13,7 @@ class TwoFactorAuthNotification extends Notification use Queueable; private $user; + private $code; /** diff --git a/ProcessMaker/Observers/ProcessRequestObserver.php b/ProcessMaker/Observers/ProcessRequestObserver.php index d412de745f..684b793384 100644 --- a/ProcessMaker/Observers/ProcessRequestObserver.php +++ b/ProcessMaker/Observers/ProcessRequestObserver.php @@ -104,7 +104,7 @@ public function created(ProcessRequest $request) ->select('case_number') ->first() ->case_number; - + $request->save(); return; diff --git a/ProcessMaker/Observers/UserObserver.php b/ProcessMaker/Observers/UserObserver.php index 3acecbb4b8..36c14ca046 100644 --- a/ProcessMaker/Observers/UserObserver.php +++ b/ProcessMaker/Observers/UserObserver.php @@ -36,7 +36,7 @@ public function deleting(User $user) public function created(User $user): void { $perList = [ - 'view-process-catalog' + 'view-process-catalog', ]; $permissionIds = Permission::whereIn('name', $perList)->pluck('id')->toArray(); $user->permissions()->attach($permissionIds); diff --git a/ProcessMaker/TwoFactorAuthentication.php b/ProcessMaker/TwoFactorAuthentication.php index 1f22d30c4f..4fe8f04807 100644 --- a/ProcessMaker/TwoFactorAuthentication.php +++ b/ProcessMaker/TwoFactorAuthentication.php @@ -2,8 +2,8 @@ namespace ProcessMaker; -use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\Image\SvgImageBackEnd; +use BaconQrCode\Renderer\ImageRenderer; use BaconQrCode\Renderer\RendererStyle\RendererStyle; use BaconQrCode\Writer; use Illuminate\Support\Facades\Notification; @@ -17,8 +17,11 @@ class TwoFactorAuthentication { const EMAIL = 'By email'; + const SMS = 'By message to phone number'; + const AUTH_APP = 'Authenticator App'; + const ERROR_INVALID_TO_NUMBER = 21211; public function sendCode(User $user): void @@ -45,6 +48,7 @@ public function sendCode(User $user): void private function generateSecret(User $user): string { $base = $user->uuid . '_' . $user->username; + return trim(Base32::encodeUpper($base), '='); } @@ -116,7 +120,7 @@ private function sendSms(User $user, string $code) $twilio->messages->create($to, [ 'from' => $from, - 'body' => $body + 'body' => $body, ] ); } catch (TwilioException $error) { @@ -179,7 +183,7 @@ public function friendlyMethodsNames(User $user, array $enabledMethods = []) } // Return the friendly names for enabled methods - $methods = array_map(function($method) use ($friendlyNames) { + $methods = array_map(function ($method) use ($friendlyNames) { return $friendlyNames[$method] ?? $method; }, $enabledMethods); diff --git a/composer.json b/composer.json index d3feb42538..d103e5b5c8 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "processmaker/processmaker", - "version": "4.9.0+nightly-20240117", + "version": "4.9.0+nightly-20240118", "description": "BPM PHP Software", "keywords": [ "php bpm processmaker" @@ -101,7 +101,7 @@ "Gmail" ], "processmaker": { - "build": "0e63d414", + "build": "6a7da65f", "custom": { "package-ellucian-ethos": "1.14.3", "package-plaid": "1.3.1", @@ -142,7 +142,7 @@ "package-advanced-user-manager": "1.9.0", "package-ai": "1.4.17", "package-analytics-reporting": "1.4.3", - "package-auth": "1.15.2", + "package-auth": "1.16.0", "package-cdata": "1.1.1", "package-collections": "2.15.3", "package-comments": "1.10.1", @@ -153,7 +153,7 @@ "package-files": "1.11.2", "package-googleplaces": "1.9.0", "package-photo-video": "1.2.0", - "package-pm-blocks": "1.4.3", + "package-pm-blocks": "1.4.4", "package-process-documenter": "1.8.0", "package-process-optimization": "1.9.0", "package-product-analytics": "1.5.8", @@ -165,7 +165,7 @@ "package-translations": "2.7.0", "package-versions": "1.8.2", "package-vocabularies": "2.13.0", - "package-webentry": "2.18.1", + "package-webentry": "2.19.0", "packages": "^0" }, "docker-executors": { diff --git a/composer.lock b/composer.lock index 812730a876..8e788f4819 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "831d71a6b429a6d7bcd23bdf9d47a8da", + "content-hash": "4dc919ec8023b3f1e3de57679c19c015", "packages": [ { "name": "aws/aws-crt-php", diff --git a/database/migrations/2023_11_27_170308_add_case_title_to_processes_table.php b/database/migrations/2023_11_27_170308_add_case_title_to_processes_table.php index 0b75970e93..7fec1600ea 100644 --- a/database/migrations/2023_11_27_170308_add_case_title_to_processes_table.php +++ b/database/migrations/2023_11_27_170308_add_case_title_to_processes_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_11_27_180941_add_case_title_number_to_process_requests_table.php b/database/migrations/2023_11_27_180941_add_case_title_number_to_process_requests_table.php index e276baf734..3b71f9d87d 100644 --- a/database/migrations/2023_11_27_180941_add_case_title_number_to_process_requests_table.php +++ b/database/migrations/2023_11_27_180941_add_case_title_number_to_process_requests_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_11_28_200725_add_password_changed_at_column_to_users_table.php b/database/migrations/2023_11_28_200725_add_password_changed_at_column_to_users_table.php index c40f6fa2c9..b8d052965d 100644 --- a/database/migrations/2023_11_28_200725_add_password_changed_at_column_to_users_table.php +++ b/database/migrations/2023_11_28_200725_add_password_changed_at_column_to_users_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_11_30_165723_add_launchpad_properties_at_processes.php b/database/migrations/2023_11_30_165723_add_launchpad_properties_at_processes.php index dcf410fb19..5d17231b46 100644 --- a/database/migrations/2023_11_30_165723_add_launchpad_properties_at_processes.php +++ b/database/migrations/2023_11_30_165723_add_launchpad_properties_at_processes.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_11_30_170839_create_user_process_bookmarks_table.php b/database/migrations/2023_11_30_170839_create_user_process_bookmarks_table.php index 3c113edd96..1679fcd036 100644 --- a/database/migrations/2023_11_30_170839_create_user_process_bookmarks_table.php +++ b/database/migrations/2023_11_30_170839_create_user_process_bookmarks_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_12_04_115613_add_case_number_to_process_requests_table.php b/database/migrations/2023_12_04_115613_add_case_number_to_process_requests_table.php index 917566e453..88afed3ad5 100644 --- a/database/migrations/2023_12_04_115613_add_case_number_to_process_requests_table.php +++ b/database/migrations/2023_12_04_115613_add_case_number_to_process_requests_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_12_11_180034_add_case_title_formatted_to_process_requests_table.php b/database/migrations/2023_12_11_180034_add_case_title_formatted_to_process_requests_table.php index 52b538bda8..81e84d13cd 100644 --- a/database/migrations/2023_12_11_180034_add_case_title_formatted_to_process_requests_table.php +++ b/database/migrations/2023_12_11_180034_add_case_title_formatted_to_process_requests_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2023_12_19_164230_create_user_sessions_table.php b/database/migrations/2023_12_19_164230_create_user_sessions_table.php index 2e710c996b..3a28055b1b 100644 --- a/database/migrations/2023_12_19_164230_create_user_sessions_table.php +++ b/database/migrations/2023_12_19_164230_create_user_sessions_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/database/migrations/2024_01_09_165046_add_preferences_2fa_column_to_users_table.php b/database/migrations/2024_01_09_165046_add_preferences_2fa_column_to_users_table.php index 84fbdcaf78..ef0e3e1f6c 100644 --- a/database/migrations/2024_01_09_165046_add_preferences_2fa_column_to_users_table.php +++ b/database/migrations/2024_01_09_165046_add_preferences_2fa_column_to_users_table.php @@ -4,8 +4,7 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration -{ +return new class extends Migration { /** * Run the migrations. */ diff --git a/package-lock.json b/package-lock.json index ecabec8c23..18fe239c08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,24 @@ { "name": "@processmaker/processmaker", - "version": "4.9.0+nightly-20240117", + "version": "4.9.0+nightly-20240118", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@processmaker/processmaker", - "version": "4.9.0+nightly-20240117", + "version": "4.9.0+nightly-20240118", "hasInstallScript": true, "license": "ISC", "dependencies": { "@braintree/sanitize-url": "^6.0.2", + "@fontsource/poppins": "^5.0.8", "@fortawesome/fontawesome-free": "^5.15.1", "@fortawesome/fontawesome-svg-core": "^1.2.32", "@fortawesome/free-brands-svg-icons": "^5.15.1", "@fortawesome/free-solid-svg-icons": "^5.15.1", "@fortawesome/vue-fontawesome": "^0.1.9", "@panter/vue-i18next": "^0.15.2", - "@processmaker/modeler": "1.43.18", + "@processmaker/modeler": "1.43.19", "@processmaker/processmaker-bpmn-moddle": "0.14.1", "@processmaker/screen-builder": "2.79.5", "@processmaker/vue-form-elements": "0.50.2", @@ -1807,6 +1808,11 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@fontsource/poppins": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@fontsource/poppins/-/poppins-5.0.8.tgz", + "integrity": "sha512-P8owfYWluoUY5Nyzk4gT/L6LmLmseP6ezFWhj6VBUa5pRIdnCvNJpoQ6i/vhekjtJOfqX6nKlB+LCttoUl2GQQ==" + }, "node_modules/@fortawesome/fontawesome-common-types": { "version": "0.2.36", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz", @@ -2229,9 +2235,9 @@ "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info." }, "node_modules/@processmaker/modeler": { - "version": "1.43.18", - "resolved": "https://registry.npmjs.org/@processmaker/modeler/-/modeler-1.43.18.tgz", - "integrity": "sha512-rNs+4U7MVIGs2PJaC0/MhWt/JxNp5gysvqPxUTUURHb5VmPzIBKq89N7MIMX0xnM0IjuRxxaYDwnTe0T1htYVg==", + "version": "1.43.19", + "resolved": "https://registry.npmjs.org/@processmaker/modeler/-/modeler-1.43.19.tgz", + "integrity": "sha512-Sf5CJat8b3HldZqx0vuHPFxqsuuwrBYIqSl2AHadUOk41dqJRDAuOInoTNYLXpvcPmIrrFiJOHYzsgTK7nNqzg==", "dependencies": { "@babel/plugin-proposal-private-methods": "^7.12.1", "@fortawesome/fontawesome-free": "^5.11.2", @@ -17426,6 +17432,11 @@ "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", "dev": true }, + "@fontsource/poppins": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@fontsource/poppins/-/poppins-5.0.8.tgz", + "integrity": "sha512-P8owfYWluoUY5Nyzk4gT/L6LmLmseP6ezFWhj6VBUa5pRIdnCvNJpoQ6i/vhekjtJOfqX6nKlB+LCttoUl2GQQ==" + }, "@fortawesome/fontawesome-common-types": { "version": "0.2.36", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.36.tgz", @@ -17737,9 +17748,9 @@ "integrity": "sha512-eKnrt2mCtcYFhweNr20mOWSG0431BPPFnhYJEQd+D2/5ssWPaHVEEgD3YnUOmbg1gdRQdVe2rrxcdEvvPugB/A==" }, "@processmaker/modeler": { - "version": "1.43.18", - "resolved": "https://registry.npmjs.org/@processmaker/modeler/-/modeler-1.43.18.tgz", - "integrity": "sha512-rNs+4U7MVIGs2PJaC0/MhWt/JxNp5gysvqPxUTUURHb5VmPzIBKq89N7MIMX0xnM0IjuRxxaYDwnTe0T1htYVg==", + "version": "1.43.19", + "resolved": "https://registry.npmjs.org/@processmaker/modeler/-/modeler-1.43.19.tgz", + "integrity": "sha512-Sf5CJat8b3HldZqx0vuHPFxqsuuwrBYIqSl2AHadUOk41dqJRDAuOInoTNYLXpvcPmIrrFiJOHYzsgTK7nNqzg==", "requires": { "@babel/plugin-proposal-private-methods": "^7.12.1", "@fortawesome/fontawesome-free": "^5.11.2", diff --git a/package.json b/package.json index 9afd1921a8..7915c3c105 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "@processmaker/processmaker", - "version": "4.9.0+nightly-20240117", + "version": "4.9.0+nightly-20240118", "description": "ProcessMaker 4", "author": "DevOps ", "license": "ISC", "homepage": "https://github.com/ProcessMaker/processmaker", "private": true, "scripts": { - "postinstall": "mkdir -p public/css/precompiled && cp -rf node_modules/npm-font-open-sans public/css/precompiled/npm-font-open-sans && cp -rf node_modules/bootstrap/scss public/css/precompiled/bootstrap && cp -rf node_modules/@fortawesome/fontawesome-free public/css/precompiled/fontawesome-free && cp -rf node_modules/@processmaker/vue-multiselect/dist/vue-multiselect.min.css public/css/precompiled", + "postinstall": "mkdir -p public/css/precompiled && cp -rf node_modules/npm-font-open-sans public/css/precompiled/npm-font-open-sans && cp -rf node_modules/bootstrap/scss public/css/precompiled/bootstrap && cp -rf node_modules/@fortawesome/fontawesome-free public/css/precompiled/fontawesome-free && cp -rf node_modules/@fontsource/poppins public/css/precompiled/poppins && cp -rf node_modules/@processmaker/vue-multiselect/dist/vue-multiselect.min.css public/css/precompiled", "dev": "npm run development", "development": "mix", "watch": "mix watch", @@ -41,13 +41,14 @@ }, "dependencies": { "@braintree/sanitize-url": "^6.0.2", + "@fontsource/poppins": "^5.0.8", "@fortawesome/fontawesome-free": "^5.15.1", "@fortawesome/fontawesome-svg-core": "^1.2.32", "@fortawesome/free-brands-svg-icons": "^5.15.1", "@fortawesome/free-solid-svg-icons": "^5.15.1", "@fortawesome/vue-fontawesome": "^0.1.9", "@panter/vue-i18next": "^0.15.2", - "@processmaker/modeler": "1.43.18", + "@processmaker/modeler": "1.43.19", "@processmaker/processmaker-bpmn-moddle": "0.14.1", "@processmaker/screen-builder": "2.79.5", "@processmaker/vue-form-elements": "0.50.2", diff --git a/resources/js/common/PMColumnFilterPopoverCommonMixin.js b/resources/js/common/PMColumnFilterPopoverCommonMixin.js index e7b4600569..4d76ec815d 100644 --- a/resources/js/common/PMColumnFilterPopoverCommonMixin.js +++ b/resources/js/common/PMColumnFilterPopoverCommonMixin.js @@ -4,7 +4,8 @@ const PMColumnFilterCommonMixin = { advancedFilter: [], userId: window.Processmaker.userId, viewAssignee: [], - viewParticipants: [] + viewParticipants: [], + viewProcesses: [] }; }, methods: { @@ -67,9 +68,13 @@ const PMColumnFilterCommonMixin = { ]; }, onApply(json, index) { + let oldValue, type, value; for (let i in json) { - json[i].subject.type = this.getTypeColumnFilter(json[i].subject.value); - json[i].subject.value = this.getAliasColumnForFilter(json[i].subject.value); + oldValue = json[i].subject.value; + type = this.getTypeColumnFilter(oldValue); + value = this.getAliasColumnForFilter(oldValue); + json[i].subject.type = type; + json[i].subject.value = value; } this.advancedFilterInit(this.tableHeaders.length); this.advancedFilter[index] = json; @@ -99,7 +104,7 @@ const PMColumnFilterCommonMixin = { }, getAdvancedFilter() { let flat = this.advancedFilter.flat(1); - return flat.length > 0 ? "&advanced_filter=" + JSON.stringify(flat) : ""; + return flat.length > 0 ? "&advanced_filter=" + encodeURIComponent(JSON.stringify(flat)) : ""; }, getUrlUsers(filter) { let page = 1; @@ -119,7 +124,7 @@ const PMColumnFilterCommonMixin = { if (column.format) { format = column.format; } - if (column.field === "status" || column.field === "assignee" || column.field === "participants") { + if (column.field === "status" || column.field === "assignee" || column.field === "participants" || column.field === 'process') { format = "stringSelect"; } return format; @@ -135,11 +140,14 @@ const PMColumnFilterCommonMixin = { if (column.field === "participants") { formatRange = this.viewParticipants; } + if (column.field === "process") { + formatRange = this.viewProcesses; + } return formatRange; }, getOperators(column) { let operators = []; - if (column.field === "status" || column.field === "assignee" || column.field === "participants") { + if (column.field === "status" || column.field === "assignee" || column.field === "participants" || column.field === 'process') { operators = ["=", "in"]; } return operators; @@ -147,14 +155,30 @@ const PMColumnFilterCommonMixin = { getAssignee(filter) { ProcessMaker.apiClient.get(this.getUrlUsers(filter)).then(response => { for (let i in response.data.data) { - this.viewAssignee.push(response.data.data[i].username); + this.viewAssignee.push({ + text: response.data.data[i].username, + value: response.data.data[i].id + }); } }); }, getParticipants(filter) { ProcessMaker.apiClient.get(this.getUrlUsers(filter)).then(response => { for (let i in response.data.data) { - this.viewParticipants.push(response.data.data[i].username); + this.viewParticipants.push({ + text: response.data.data[i].username, + value: response.data.data[i].id + }); + } + }); + }, + getProcess() { + ProcessMaker.apiClient.get('/processes?per_page=100').then(response => { + for (let i in response.data.data) { + this.viewProcesses.push({ + text: response.data.data[i].name, + value: response.data.data[i].id + }); } }); }, diff --git a/resources/js/components/AvatarImage.vue b/resources/js/components/AvatarImage.vue index 389b84a733..17bbc9e49b 100644 --- a/resources/js/components/AvatarImage.vue +++ b/resources/js/components/AvatarImage.vue @@ -1,6 +1,8 @@ @@ -68,7 +72,11 @@ export default { characterLimit: { type: Number, default: null, - } + }, + vertical: { + type: Boolean, + default: false, + }, }, data() { return { @@ -250,4 +258,8 @@ export default { opacity: 1; pointer-events: none; } + .vertical-view { + padding-top: 4px; + padding-bottom: 4px; + } diff --git a/resources/js/components/PMColumnFilterPopover/PMColumnFilterOpSelect.vue b/resources/js/components/PMColumnFilterPopover/PMColumnFilterOpSelect.vue index a2af3d94b3..cfc94856da 100644 --- a/resources/js/components/PMColumnFilterPopover/PMColumnFilterOpSelect.vue +++ b/resources/js/components/PMColumnFilterPopover/PMColumnFilterOpSelect.vue @@ -12,7 +12,7 @@ ], data() { return { - input: "" + input: null }; }, watch: { diff --git a/resources/js/components/shared/ModalSaveVersion.vue b/resources/js/components/shared/ModalSaveVersion.vue index 3100c4e882..24132ee047 100644 --- a/resources/js/components/shared/ModalSaveVersion.vue +++ b/resources/js/components/shared/ModalSaveVersion.vue @@ -45,7 +45,7 @@ - @@ -61,7 +61,7 @@ @@ -71,7 +71,7 @@ > + + + diff --git a/resources/js/processes/components/ProcessesListing.vue b/resources/js/processes/components/ProcessesListing.vue index 3ce7b221fa..cf8902697e 100644 --- a/resources/js/processes/components/ProcessesListing.vue +++ b/resources/js/processes/components/ProcessesListing.vue @@ -13,6 +13,20 @@ :data="data" style="height: calc(100vh - 350px);" > + +