Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring most of the project #73

Merged
merged 100 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
8a4887e
[Remove db abstract] Moved already good table classes to a new place.
Nov 8, 2021
86e4dd9
[Remove db abstract] Refactored and cleaned up the user's related tab…
Nov 11, 2021
efee04f
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
Nov 11, 2021
2353108
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
Nov 12, 2021
3e7bd54
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
Nov 15, 2021
77d31ea
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
Nov 16, 2021
0c5b3ee
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
Mar 24, 2022
1a4d5c6
CS fixes and conditions improvements.
Mar 24, 2022
1c965f6
Restructured and removed some services and the vulnerability table.
Mar 30, 2022
d948508
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
Apr 1, 2022
72002dd
Added the AnrValidationMiddleware.
May 17, 2022
d762043
Implemented the support of middleware and possibility to dispatch mcv…
May 19, 2022
1235fd3
Merged master branch into feature/remove-db-abstract.
Nov 22, 2022
305484f
Merged master branch into the feature/remove-db-abstract, partially a…
Nov 25, 2022
270e962
Removed the method due to the move to the inherited core table class.
Feb 8, 2023
39c8779
Removed the locally_touched and object_id fields from the instances_c…
Feb 13, 2023
b7c4813
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
Feb 13, 2023
1827b39
Replaced some services methods declarations and tables usage.
Feb 13, 2023
52641e9
First steps of the refactoring related to the core changes.
Mar 6, 2023
cc534a1
Implied the changes from Core side to the FrontOffice, added migratio…
ruslanbaidan Aug 22, 2023
11a5a11
The entities cleanup.
ruslanbaidan Aug 23, 2023
f8c49d6
Added the to the migration unique label for anrs, fixed threat, asset…
ruslanbaidan Aug 25, 2023
8c1302b
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
ruslanbaidan Sep 18, 2023
870ed8a
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
ruslanbaidan Oct 18, 2023
93142a0
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
ruslanbaidan Nov 17, 2023
59b8f2c
Fixed the core version.
ruslanbaidan Nov 17, 2023
bb84b49
Fixed the PHP version for the build.
ruslanbaidan Nov 17, 2023
c3feea8
Upodated the workflow with the composer install fix.
ruslanbaidan Nov 17, 2023
bc61bc7
Refactored instance risks, recommendations, anr single label and lang…
ruslanbaidan Jan 19, 2024
60db3c6
Code styles fixes.
ruslanbaidan Jan 19, 2024
f651822
Updated the operational risks functionality.
ruslanbaidan Jan 25, 2024
a7cd852
Updated the deliveries, cartography services, controllers methods and…
ruslanbaidan Feb 11, 2024
ab595aa
Completed the scales related functionality change.
ruslanbaidan Feb 16, 2024
e15b8da
CS fixes.
ruslanbaidan Feb 16, 2024
8b63132
Finished the objects, categories and composition functionality update…
ruslanbaidan Feb 20, 2024
3fc9553
Moved the anr status and access validation to the middleware, refacto…
ruslanbaidan Mar 13, 2024
242f31f
Code styles fixes.
ruslanbaidan Mar 13, 2024
c5ab9c2
Fixed the migration and the JS recommendation service name.
ruslanbaidan Mar 13, 2024
908b574
Moved all the entities to the src folder, fixed the controllers respo…
ruslanbaidan Mar 17, 2024
f668837
Removed useless anr validation across the controllers, fixed some ser…
ruslanbaidan Mar 18, 2024
bf73282
Fixed the recommendations validator and patch method, fixed the Rolf …
ruslanbaidan Mar 18, 2024
5d253e2
Fixed the soa fetching.
ruslanbaidan Mar 19, 2024
13b0b78
Fixed the recursive call, added the validator definition.
ruslanbaidan Mar 19, 2024
ab173c2
Fixed the fitching of instance risk by instance id, removed the extra…
ruslanbaidan Mar 19, 2024
5065834
Fixed the org settings setup, instances metadata table.
ruslanbaidan Mar 20, 2024
b99639e
Fixed the positions update for Amv and Objects compositions.
ruslanbaidan Mar 21, 2024
cc59653
Fixed the instance risks evaluation, objects creation and instance co…
ruslanbaidan Mar 23, 2024
c2fd490
Fixed the recommendations risks fetching and recommendations patch.
ruslanbaidan Mar 23, 2024
41997df
Fixed the params names to "cacheTargetedRisk"
ruslanbaidan Mar 23, 2024
dbfec07
Fixed some anr creation issues.
ruslanbaidan Mar 23, 2024
fcd4831
Refactroed the Referential, Measure, SoaCategory functionality, other…
ruslanbaidan Apr 20, 2024
9ea0b3c
Fixed the CS.
ruslanbaidan Apr 21, 2024
6b94193
Prepared the export functionality.
ruslanbaidan May 2, 2024
493062a
Removed the extra MeasureMeasure entity and its table, dropped all th…
ruslanbaidan May 29, 2024
9e634d7
Improved the export and extended import, removed the objects position…
ruslanbaidan Jun 10, 2024
b8d07ea
Finalized the library assets import process.
ruslanbaidan Jun 14, 2024
727e1c8
Added multiple import processors, refactored soa functionality and im…
ruslanbaidan Jul 4, 2024
d893f51
Finished all of the importing scenarios.
ruslanbaidan Jul 23, 2024
d9f1840
Fixed the processor to support the old format and object import type.
ruslanbaidan Jul 24, 2024
208aac1
Fixed the import process issues.
ruslanbaidan Jul 25, 2024
9c79282
Fixed the import conditions and added referentials when soa is export…
ruslanbaidan Jul 26, 2024
80f64f3
Fixed the export and import issues, snapshots restoring, recommendati…
ruslanbaidan Aug 20, 2024
9744558
Added the threat validation to manage the evaluation and treands upda…
ruslanbaidan Aug 21, 2024
ca4d06c
CS fix.
ruslanbaidan Aug 21, 2024
819f62a
Fixed the nullable op risks scale comment issue.
ruslanbaidan Aug 22, 2024
8c5159a
Fixed the table name in the consturctor and errors processing in the …
ruslanbaidan Aug 22, 2024
d60283d
Fixed the converter of the recommendation's set data and the steps bl…
ruslanbaidan Aug 23, 2024
e7d0f53
FIxed, reports generation, CSV risks export, 4th step validation, op …
ruslanbaidan Aug 26, 2024
22970c0
Fixed the recommendations sibling setup and objects import from the l…
ruslanbaidan Aug 26, 2024
3e5e049
Fixed the recommendations duplication in the report and in the risks …
ruslanbaidan Aug 27, 2024
cb48b64
Fixed the op risks scales cache preparation
ruslanbaidan Aug 27, 2024
034b209
Added the necessary data for the dashboard rendering.
ruslanbaidan Aug 28, 2024
fa1559e
Removed the user's details from the password reset response.
ruslanbaidan Aug 28, 2024
b373079
Fixed the response of the reset password action.
ruslanbaidan Aug 28, 2024
87db5ff
Updated the copyright comment.
ruslanbaidan Aug 30, 2024
2fd1872
Added the profile update email validation.
ruslanbaidan Aug 30, 2024
9ea2219
Fixed the recommendation validation history creation.
ruslanbaidan Sep 1, 2024
3724941
Fixed the history query generation.
ruslanbaidan Sep 1, 2024
3a0c013
Added the flag of the risk type associated to the history of validate…
ruslanbaidan Sep 1, 2024
eeb8aa2
Fixed the reports download and ropa generation.
ruslanbaidan Sep 3, 2024
5fca28d
Fixed the instance evaluation setting up during the import.
ruslanbaidan Sep 3, 2024
b7d726f
Fixed the import of scale type for instances, corrected convertion of…
ruslanbaidan Sep 5, 2024
d3332df
Fixed the issue of the wrong old export files.
ruslanbaidan Sep 6, 2024
ab3b5fb
Added the existing control property to the recommendations risks resp…
ruslanbaidan Sep 6, 2024
096ed6f
Updated the composer.json to go for the release.
ruslanbaidan Sep 6, 2024
0751a28
Fixed the deliveries generation.
ruslanbaidan Sep 10, 2024
b1aba7c
Temporary reverted the core version load.
ruslanbaidan Sep 10, 2024
3fc9664
Fixed the ropa update action.
ruslanbaidan Sep 11, 2024
c517ab5
Fixed the anr fetch call.
ruslanbaidan Sep 11, 2024
060b6a7
Updated the readme file.
ruslanbaidan Sep 11, 2024
e26725f
Merge remote-tracking branch 'origin/master' into feature/remove-db-a…
ruslanbaidan Sep 13, 2024
b55092a
Fixed the possible nullable values typecasting to string.
ruslanbaidan Sep 13, 2024
b1f16f5
Added the condition for the console run to allow user being nullable.
ruslanbaidan Sep 16, 2024
145e488
Fixed the soa categories batch creation, added the scale comment inde…
ruslanbaidan Sep 23, 2024
9baab63
FIxed the soa category id set on the batch create.
ruslanbaidan Sep 23, 2024
17b2359
Added the mssing properties set on the analysis duplication.
ruslanbaidan Sep 23, 2024
9d9fed4
Fixed the amv response to display previous element, and recommendatio…
ruslanbaidan Sep 26, 2024
f0ed0ee
Fixed the operational risks saving and creation of library objects wi…
ruslanbaidan Sep 27, 2024
ed72ee3
Added the system messages functionality.
ruslanbaidan Oct 2, 2024
a5b2203
Some code cleanup.
ruslanbaidan Oct 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/workflows/phpcs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
php-version: '8.1'
extensions: imagick, intl, mysql, bcmath, openssl
ini-values: post_max_size=256M, short_open_tag=On
tools: pecl, cs2pr, phpcs
Expand All @@ -33,7 +33,7 @@ jobs:
${{ runner.os }}-php-

- name: Install dependencies
run: composer install --prefer-dist --no-progress
run: composer install --prefer-dist --no-progress --no-suggest --ignore-platform-req=php

# Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit"
# Docs: https://getcomposer.org/doc/articles/scripts.md
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
vendor/
composer.lock
.idea/
.phpcs*
244 changes: 48 additions & 196 deletions Module.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
<?php
<?php declare(strict_types=1);
/**
* @link https://github.com/monarc-project for the canonical source repository
* @copyright Copyright (c) 2016-2024 Luxembourg House of Cybersecurity LHC.lu - Licensed under GNU Affero GPL v3
* @license MONARC is licensed under GNU Affero General Public License version 3
*/

namespace Monarc\FrontOffice;

use DateTime;
use Laminas\Stdlib\ResponseInterface;
use Monarc\Core\Model\Entity\AnrSuperClass;
use Monarc\Core\Service\ConnectedUserService;
use Monarc\FrontOffice\CronTask\Service\CronTaskService;
use Monarc\FrontOffice\Model\Entity\Anr;
use Monarc\FrontOffice\Model\Entity\CronTask;
use Monarc\FrontOffice\Model\Table\AnrTable;
use Monarc\FrontOffice\Model\Table\InstanceTable;
use Monarc\FrontOffice\Model\Table\SnapshotTable;
use Monarc\FrontOffice\Model\Table\UserAnrTable;
use Laminas\Http\Request;
use Laminas\Mvc\ModuleRouteListener;
use Laminas\Mvc\MvcEvent;
Expand All @@ -30,9 +27,9 @@ public function onBootstrap(MvcEvent $e)

$this->initRbac($e);

$eventManager->attach(MvcEvent::EVENT_ROUTE, array($this, 'checkRbac'), 0);
$eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'onDispatchError'), 0);
$eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, array($this, 'onRenderError'), 0);
$eventManager->attach(MvcEvent::EVENT_ROUTE, [$this, 'checkRbac'], 0);
$eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this, 'onDispatchError'], 0);
$eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, [$this, 'onRenderError'], 0);
}
}

Expand All @@ -55,51 +52,56 @@ public function getJsonModelError($e)
{
$error = $e->getError();
if (!$error) {
return;
return null;
}

$exception = $e->getParam('exception');
$exceptionJson = array();
$exceptionJson = [];
if ($exception) {
$exceptionJson = array(
'class' => get_class($exception),
$exceptionJson = [
'class' => \get_class($exception),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'message' => $exception->getMessage(),
'stacktrace' => $exception->getTraceAsString()
);
'stacktrace' => $exception->getTraceAsString(),
];

if ($exception->getCode() >= 400 && $exception->getCode() < 600) {
$e->getResponse()->setStatusCode($exception->getCode());
}
}
$errorJson = array(
'message' => $exception
? $exception->getMessage() : 'An error occurred during execution; please try again later.',
'error' => $error,
$errorJson = [
'message' => $exception
? $exception->getMessage()
: 'An error occurred during execution; please try again later.',
'error' => $error,
'exception' => $exceptionJson,
);
];
if ($error === 'error-router-no-match') {
$errorJson['message'] = 'Resource not found.';
}
$model = new JsonModel(array('errors' => array($errorJson)));

if ($exception && $exception->getCode() === 400) {
$model = new JsonModel([
'errors' => [json_decode($exception->getMessage(), true, 512, JSON_THROW_ON_ERROR)],
]);
} else {
$model = new JsonModel(['errors' => [$errorJson]]);
}

$e->setResult($model);

return $model;
}

/**
* init Rbac
*
* @param MvcEvent $e
*/
public function initRbac(MvcEvent $e)
public function initRbac(MvcEvent $mvcEvent)
{
$sm = $e->getApplication()->getServiceManager();
$sm = $mvcEvent->getApplication()->getServiceManager();
$config = $sm->get('Config');

$globalPermissions = isset($config['permissions']) ? $config['permissions'] : [];
$globalPermissions = $config['permissions'] ?? [];

$rolesPermissions = isset($config['roles']) ? $config['roles'] : [];
$rolesPermissions = $config['roles'] ?? [];

$rbac = new Rbac();
foreach ($rolesPermissions as $role => $permissions) {
Expand Down Expand Up @@ -132,186 +134,36 @@ public function initRbac(MvcEvent $e)
$rbac->addRole($role);

//setting to view
$e->getViewModel()->rbac = $rbac;
$mvcEvent->getViewModel()->rbac = $rbac;
}

/**
* Check Rbac
* @param MvcEvent $mvcEvent
*
* @param MvcEvent $e
* @return \Laminas\Stdlib\ResponseInterface
* @return ResponseInterface|void
*/
public function checkRbac(MvcEvent $e)
public function checkRbac(MvcEvent $mvcEvent)
{
$route = $e->getRouteMatch()->getMatchedRouteName();
$sm = $e->getApplication()->getServiceManager();
$route = $mvcEvent->getRouteMatch()->getMatchedRouteName();
$serviceManager = $mvcEvent->getApplication()->getServiceManager();

/** @var ConnectedUserService $connectedUserService */
$connectedUserService = $sm->get(ConnectedUserService::class);
$connectedUserService = $serviceManager->get(ConnectedUserService::class);
$connectedUser = $connectedUserService->getConnectedUser();

$roles[] = 'guest';
if ($connectedUser !== null) {
$roles = $connectedUser->getRoles();
$roles = $connectedUser->getRolesArray();
}

$isGranted = false;
foreach ($roles as $role) {
if ($e->getViewModel()->rbac->isGranted($role, $route)) {
$id = (int)$e->getRouteMatch()->getParam('id');
if (($route === 'monarc_api_client_anr' && !empty($id))
|| strncmp($route, 'monarc_api_global_client_anr/', 29) === 0
) {
if ($route === 'monarc_api_client_anr') {
$anrid = $id;
} else {
$anrid = (int)$e->getRouteMatch()->getParam('anrid');
}
if (empty($anrid)) {
break;
}

$result = $this->validateAnrStatusAndGetResponseIfInvalid($anrid, $e, $route);
if ($result !== null) {
return $result;
}

$lk = current($sm->get(UserAnrTable::class)->getEntityByFields(
['anr' => $anrid, 'user' => $connectedUser->getId()]
));
if (empty($lk)) {
// On doit tester si c'est un snapshot, dans ce cas, on autorise l'accès mais en READ-ONLY
if ($e->getRequest()->getMethod() !== Request::METHOD_GET
&& !$this->authorizedPost($route, $e->getRequest()->getMethod())
) {
break; // même si c'est un snapshot, on n'autorise que du GET
}
$snap = current($sm->get(SnapshotTable::class)->getEntityByFields(['anr' => $anrid]));
if (empty($snap)) {
break; // ce n'est pas un snapshot
}
$lk = current($sm->get(UserAnrTable::class)->getEntityByFields(
['anr' => $snap->get('anrReference')->get('id'), 'user' => $connectedUser->getId()]
));
if (empty($lk)) {
break; // l'user n'avait de toute façon pas accès à l'anr dont est issue ce snapshot
}
$isGranted = true;
break;
}

if ($lk->get('rwd') === 0 && $e->getRequest()->getMethod() !== Request::METHOD_GET) {
if ($this->authorizedPost($route, $e->getRequest()->getMethod())) {
// on autorise les POST pour les export
$isGranted = true;
}
break; // les droits ne sont pas bon
}
}

$isGranted = true;
break;
}
}

if (!$isGranted) {
$response = $e->getResponse();
$response->setStatusCode($connectedUser === null ? 401 : 403);

return $response;
}
}

private function authorizedPost($route, $method)
{
return $method === 'POST' &&
($route === 'monarc_api_global_client_anr/export' || // export ANR
$route === 'monarc_api_global_client_anr/instance_export' || // export Instance
$route === 'monarc_api_global_client_anr/objects_export' || // export Object
$route === 'monarc_api_global_client_anr/deliverable'); // generate a report
}

/**
* Validates the anr status for NON GET method requests exclude DELETE (cancellation of background import).
*/
private function validateAnrStatusAndGetResponseIfInvalid(
int $anrId,
MvcEvent $e,
string $route
): ?ResponseInterface {
/* GET requests are always allowed and cancellation of import (delete import process -> PID). */
if ($e->getRequest()->getMethod() === Request::METHOD_GET
|| (
$e->getRequest()->getMethod() === Request::METHOD_DELETE
&& $route === 'monarc_api_global_client_anr/instance_import'
)
) {
return null;
}

$sm = $e->getApplication()->getServiceManager();

/** @var Anr $anr */
$anr = $sm->get(AnrTable::class)->findById($anrId);
if ($anr->isActive()) {
return null;
}

/* Allow deleting anr if the status is waiting for import or there is an import error. */
if ($route === 'monarc_api_client_anr'
&& $e->getRequest()->getMethod() === Request::METHOD_DELETE
&& ($anr->getStatus() === AnrSuperClass::STATUS_IMPORT_ERROR
|| $anr->getStatus() === AnrSuperClass::STATUS_AWAITING_OF_IMPORT
)
) {
return null;
}

/* Allow to restore a snapshot if there is an import error. */
if ($route === 'monarc_api_global_client_anr/snapshot_restore'
&& $anr->getStatus() === AnrSuperClass::STATUS_IMPORT_ERROR
&& $e->getRequest()->getMethod() === Request::METHOD_POST
) {
return null;
}

$result = [
'status' => $anr->getStatusName(),
'importStatus' => [],
];
/** @var CronTaskService $cronTaskService */
$cronTaskService = $sm->get(CronTaskService::class);

if ($anr->getStatus() === AnrSuperClass::STATUS_UNDER_IMPORT) {
$importCronTask = $cronTaskService->getLatestTaskByNameWithParam(
CronTask::NAME_INSTANCE_IMPORT,
['anrId' => $anrId]
);
if ($importCronTask !== null && $importCronTask->getStatus() === CronTask::STATUS_IN_PROGRESS) {
/** @var InstanceTable $instanceTable */
$instanceTable = $sm->get(InstanceTable::class);
$timeDiff = $importCronTask->getUpdatedAt()->diff(new DateTime());
$instancesNumber = $instanceTable->countByAnrIdFromDate($anrId, $importCronTask->getUpdatedAt());
$result['importStatus'] = [
'executionTime' => $timeDiff->h . ' hours ' . $timeDiff->i . ' min ' . $timeDiff->s . ' sec',
'createdInstances' => $instancesNumber,
];
}
} elseif ($anr->getStatus() === AnrSuperClass::STATUS_IMPORT_ERROR) {
$importCronTask = $cronTaskService->getLatestTaskByNameWithParam(
CronTask::NAME_INSTANCE_IMPORT,
['anrId' => $anrId]
);
if ($importCronTask !== null && $importCronTask->getStatus() === CronTask::STATUS_FAILURE) {
$result['importStatus'] = [
'errorMessage' => $importCronTask->getResultMessage(),
];
if ($mvcEvent->getViewModel()->rbac->isGranted($role, $route)) {
return;
}
}

$response = $e->getResponse();
$response->setContent(json_encode($result, JSON_THROW_ON_ERROR));
$response->setStatusCode(409);
$response = $mvcEvent->getResponse();
$response->setStatusCode($connectedUser === null ? 401 : 403);

return $response;
}
Expand Down
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
MONARC client project
=====================

Objective
---------

The backend part of the FrontOffice tool. It provides all the api endpoints to server the frontend calls with the json data.
The export/import functionality as wells as statistics aggregation is the other side of the functionality of the project.
It is dependent on the zm-core projects.


Middleware
----------

There is a AnrValidationMiddleware that is processed before the controllers actions and performs the anr access validation and some related endpoints access.
In case if the middleware validations passed successfully the anr object is added to the attribute of the request and can be accessible across all the /client-anr based controllers/actions.

License
-------

This software is licensed under [GNU Affero General Public License version 3](http://www.gnu.org/licenses/agpl-3.0.html)

Copyright (C) 2016-2020 SMILE gie securitymadein.lu
- Copyright (C) 2022-2024 Luxembourg House of Cybersecurity https://lhc.lu
- Copyright (C) 2016-2022 SMILE gie securitymadein.lu
- Copyright (C) 2016-2024 Jérôme Lombardi - https://github.com/jerolomb
- Copyright (C) 2016-2024 Juan Rocha - https://github.com/jfrocha
- Copyright (C) 2017-2024 Cédric Bonhomme - https://www.cedricbonhomme.org
- Copyright (C) 2019-2024 Ruslan Baidan - https://github.com/ruslanbaidan
9 changes: 6 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,24 +41,27 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.0",
"ext-intl": "*",
"ext-imagick": "*",
"ext-json": "*",
"ext-bcmath": "*",
"ext-openssl": "*",
"ext-posix": "*",
"doctrine/doctrine-orm-module": "^5.1",
"monarc/core": "^2.12.6",
"monarc/core": "dev-feature/remove-db-abstract as v2.12.7",
"robmorgan/phinx": "^0.13.4",
"laminas/laminas-di": "^3.1",
"laminas/laminas-mvc": "^3.1",
"laminas/laminas-mvc-console": "^1.2",
"laminas/laminas-permissions-rbac": "^3.0",
"laminas/laminas-filter": "^2.9",
"laminas/laminas-inputfilter": "^2.10",
"laminas/laminas-dependency-plugin": "^2.0",
"symfony/console": "^5.0",
"guzzlehttp/guzzle": "^6.5",
"phpoffice/phpword": "^0.18.1"
"phpoffice/phpword": "^0.18.1",
"laminas/laminas-mvc-middleware": "^2.2"
},
"require-dev": {
"roave/security-advisories": "dev-master"
Expand Down
Loading
Loading