middleware api
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Api;
|
||||
|
||||
use Espo\Core\InjectableFactory;
|
||||
use Espo\Core\Utils\Metadata;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
|
||||
class MiddlewareProvider
|
||||
{
|
||||
public function __construct(
|
||||
private Metadata $metadata,
|
||||
private InjectableFactory $injectableFactory
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @return MiddlewareInterface[]
|
||||
*/
|
||||
public function getGlobalMiddlewareList(): array
|
||||
{
|
||||
return $this->createFromClassNameList($this->getGlobalMiddlewareClassNameList());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MiddlewareInterface[]
|
||||
*/
|
||||
public function getRouteMiddlewareList(Route $route): array
|
||||
{
|
||||
$key = strtolower($route->getMethod()) . '_' . $route->getRoute();
|
||||
|
||||
/** @var class-string<MiddlewareInterface>[] $classNameList */
|
||||
$classNameList = $this->metadata->get(['app', 'api', 'routeMiddlewareClassNameListMap', $key]) ?? [];
|
||||
|
||||
return $this->createFromClassNameList($classNameList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MiddlewareInterface[]
|
||||
*/
|
||||
public function getControllerMiddlewareList(string $controller): array
|
||||
{
|
||||
/** @var class-string<MiddlewareInterface>[] $classNameList */
|
||||
$classNameList = $this->metadata
|
||||
->get(['app', 'api', 'controllerMiddlewareClassNameListMap', $controller]) ?? [];
|
||||
|
||||
return $this->createFromClassNameList($classNameList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MiddlewareInterface[]
|
||||
*/
|
||||
public function getControllerActionMiddlewareList(string $method, string $controller, string $action): array
|
||||
{
|
||||
$key = $controller . '_' . strtolower($method) . '_' . $action;
|
||||
|
||||
/** @var class-string<MiddlewareInterface>[] $classNameList */
|
||||
$classNameList = $this->metadata
|
||||
->get(['app', 'api', 'controllerActionMiddlewareClassNameListMap', $key]) ?? [];
|
||||
|
||||
return $this->createFromClassNameList($classNameList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return class-string<MiddlewareInterface>[]
|
||||
*/
|
||||
private function getGlobalMiddlewareClassNameList(): array
|
||||
{
|
||||
return $this->metadata->get(['app', 'api', 'globalMiddlewareClassNameList']) ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string<MiddlewareInterface>[] $classNameList
|
||||
* @return MiddlewareInterface[]
|
||||
*/
|
||||
private function createFromClassNameList(array $classNameList): array
|
||||
{
|
||||
$list = [];
|
||||
|
||||
foreach ($classNameList as $className) {
|
||||
$list[] = $this->injectableFactory->create($className);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class RequestProcessor
|
||||
$this->processInternal($route, $request, $response);
|
||||
}
|
||||
catch (Exception $exception) {
|
||||
$this->handleException($exception, $request, $response, $route->getRoute());
|
||||
$this->handleException($exception, $request, $response, $route->getAdjustedRoute());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,24 +32,18 @@ namespace Espo\Core\Api;
|
||||
class Route
|
||||
{
|
||||
private string $method;
|
||||
private string $route;
|
||||
/** @var array<string, string> */
|
||||
private array $params;
|
||||
private bool $noAuth;
|
||||
|
||||
/**
|
||||
* @param array<string, string> $params
|
||||
*/
|
||||
public function __construct(
|
||||
string $method,
|
||||
string $route,
|
||||
array $params,
|
||||
bool $noAuth
|
||||
private string $route,
|
||||
private string $adjustedRoute,
|
||||
private array $params,
|
||||
private bool $noAuth
|
||||
) {
|
||||
$this->method = strtoupper($method);
|
||||
$this->route = $route;
|
||||
$this->params = $params;
|
||||
$this->noAuth = $noAuth;
|
||||
}
|
||||
|
||||
public function getMethod(): string
|
||||
@@ -57,13 +51,24 @@ class Route
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a route.
|
||||
*/
|
||||
public function getRoute(): string
|
||||
{
|
||||
return $this->route;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string,string>
|
||||
* Get an adjusted route for FastRoute.
|
||||
*/
|
||||
public function getAdjustedRoute(): string
|
||||
{
|
||||
return $this->adjustedRoute;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getParams(): array
|
||||
{
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/************************************************************************
|
||||
* This file is part of EspoCRM.
|
||||
*
|
||||
* EspoCRM - Open Source CRM application.
|
||||
* Copyright (C) 2014-2022 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
|
||||
* Website: https://www.espocrm.com
|
||||
*
|
||||
* EspoCRM is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* EspoCRM is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions
|
||||
* of this program must display Appropriate Legal Notices, as required under
|
||||
* Section 5 of the GNU General Public License version 3.
|
||||
*
|
||||
* In accordance with Section 7(b) of the GNU General Public License version 3,
|
||||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||||
************************************************************************/
|
||||
|
||||
namespace Espo\Core\Api;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
class RouteHandler implements RequestHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @param array<string, mixed> $routeParams
|
||||
*/
|
||||
public function __construct(
|
||||
private Route $route,
|
||||
private array $routeParams,
|
||||
private string $basePath,
|
||||
private ResponseInterface $response,
|
||||
private RequestProcessor $requestProcessor
|
||||
) {}
|
||||
|
||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
$requestWrapped = new RequestWrapper($request, $this->basePath, $this->routeParams);
|
||||
$responseWrapped = new ResponseWrapper($this->response);
|
||||
|
||||
$this->requestProcessor->process($this->route, $requestWrapped, $responseWrapped);
|
||||
|
||||
return $responseWrapped->getResponse();
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ use Slim\Factory\AppFactory as SlimAppFactory;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Psr7Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Psr7Request;
|
||||
use Slim\MiddlewareDispatcher;
|
||||
|
||||
/**
|
||||
* API request processing entry point.
|
||||
@@ -48,6 +49,7 @@ class Starter
|
||||
private RequestProcessor $requestProcessor,
|
||||
private RouteUtil $routeUtil,
|
||||
private RouteParamsFetcher $routeParamsFetcher,
|
||||
private MiddlewareProvider $middlewareProvider,
|
||||
private Log $log
|
||||
) {}
|
||||
|
||||
@@ -56,12 +58,20 @@ class Starter
|
||||
$slim = SlimAppFactory::create();
|
||||
|
||||
$slim->setBasePath(RouteUtil::detectBasePath());
|
||||
$this->addGlobalMiddlewares($slim);
|
||||
$slim->addRoutingMiddleware();
|
||||
$this->addRoutes($slim);
|
||||
$slim->addErrorMiddleware(false, true, true, $this->log);
|
||||
$slim->run();
|
||||
}
|
||||
|
||||
private function addGlobalMiddlewares(SlimApp $slim): void
|
||||
{
|
||||
foreach ($this->middlewareProvider->getGlobalMiddlewareList() as $middleware) {
|
||||
$slim->add($middleware);
|
||||
}
|
||||
}
|
||||
|
||||
private function addRoutes(SlimApp $slim): void
|
||||
{
|
||||
$routeList = $this->routeUtil->getFullList();
|
||||
@@ -73,20 +83,62 @@ class Starter
|
||||
|
||||
private function addRoute(SlimApp $slim, Route $item): void
|
||||
{
|
||||
$slim->map(
|
||||
$slimRoute = $slim->map(
|
||||
[$item->getMethod()],
|
||||
$item->getRoute(),
|
||||
$item->getAdjustedRoute(),
|
||||
function (Psr7Request $request, Psr7Response $response, array $args) use ($slim, $item)
|
||||
{
|
||||
$routeParams = $this->routeParamsFetcher->fetch($item, $args);
|
||||
|
||||
$requestWrapped = new RequestWrapper($request, $slim->getBasePath(), $routeParams);
|
||||
$responseWrapped = new ResponseWrapper($response);
|
||||
$routeHandler = new RouteHandler(
|
||||
$item,
|
||||
$routeParams,
|
||||
$slim->getBasePath(),
|
||||
$response,
|
||||
$this->requestProcessor
|
||||
);
|
||||
|
||||
$this->requestProcessor->process($item, $requestWrapped, $responseWrapped);
|
||||
$dispatcher = new MiddlewareDispatcher($routeHandler);
|
||||
|
||||
return $responseWrapped->getResponse();
|
||||
$this->addControllerMiddlewares($dispatcher, $item, $routeParams);
|
||||
|
||||
return $dispatcher->handle($request);
|
||||
}
|
||||
);
|
||||
|
||||
$middlewareList = $this->middlewareProvider->getRouteMiddlewareList($item);
|
||||
|
||||
foreach ($middlewareList as $middleware) {
|
||||
$slimRoute->addMiddleware($middleware);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $routeParams
|
||||
*/
|
||||
private function addControllerMiddlewares(MiddlewareDispatcher $dispatcher, Route $route, array $routeParams): void
|
||||
{
|
||||
$controller = $routeParams['controller'] ?? null;
|
||||
$action = $routeParams['action'] ?? null;
|
||||
|
||||
if (!$controller) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($action) {
|
||||
$controllerActionMiddlewareList = $this->middlewareProvider
|
||||
->getControllerActionMiddlewareList($route->getMethod(), $controller, $action);
|
||||
|
||||
foreach ($controllerActionMiddlewareList as $middleware) {
|
||||
$dispatcher->addMiddleware($middleware);
|
||||
}
|
||||
}
|
||||
|
||||
$controllerMiddlewareList = $this->middlewareProvider
|
||||
->getControllerMiddlewareList($controller);
|
||||
|
||||
foreach ($controllerMiddlewareList as $middleware) {
|
||||
$dispatcher->addMiddleware($middleware);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
namespace Espo\Core\Portal\Api;
|
||||
|
||||
use Espo\Core\Api\MiddlewareProvider;
|
||||
use Espo\Core\Api\Starter as StarterBase;
|
||||
use Espo\Core\Portal\Utils\Route as RouteUtil;
|
||||
use Espo\Core\Api\RequestProcessor;
|
||||
@@ -41,12 +42,14 @@ class Starter extends StarterBase
|
||||
RequestProcessor $requestProcessor,
|
||||
RouteUtil $routeUtil,
|
||||
RouteParamsFetcher $routeParamsFetcher,
|
||||
MiddlewareProvider $middlewareProvider,
|
||||
Log $log
|
||||
) {
|
||||
parent::__construct(
|
||||
$requestProcessor,
|
||||
$routeUtil,
|
||||
$routeParamsFetcher,
|
||||
$middlewareProvider,
|
||||
$log
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class Route extends BaseRoute
|
||||
$newRouteList = [];
|
||||
|
||||
foreach ($originalRouteList as $route) {
|
||||
$path = $route->getRoute();
|
||||
$path = $route->getAdjustedRoute();
|
||||
|
||||
if ($path[0] !== '/') {
|
||||
$path = '/' . $path;
|
||||
@@ -51,6 +51,7 @@ class Route extends BaseRoute
|
||||
|
||||
$newRoute = new RouteItem(
|
||||
$route->getMethod(),
|
||||
$route->getRoute(),
|
||||
$path,
|
||||
$route->getParams(),
|
||||
$route->noAuth()
|
||||
|
||||
@@ -69,7 +69,7 @@ class Metadata
|
||||
private $changedData = [];
|
||||
|
||||
/**
|
||||
* @var array<int,string[]>
|
||||
* @var array<int, string[]>
|
||||
*/
|
||||
private $forceAppendPathList = [
|
||||
['app', 'rebuild', 'actionClassNameList'],
|
||||
@@ -77,6 +77,10 @@ class Metadata
|
||||
['app', 'fieldProcessing', 'listLoaderClassNameList'],
|
||||
['app', 'fieldProcessing', 'saverClassNameList'],
|
||||
['app', 'hook', 'suppressClassNameList'],
|
||||
['app', 'api', 'globalMiddlewareClassNameList'],
|
||||
['app', 'api', 'routeMiddlewareClassNameListMap', self::ANY_KEY],
|
||||
['app', 'api', 'controllerMiddlewareClassNameListMap', self::ANY_KEY],
|
||||
['app', 'api', 'controllerActionMiddlewareClassNameListMap', self::ANY_KEY],
|
||||
['recordDefs', self::ANY_KEY, 'readLoaderClassNameList'],
|
||||
['recordDefs', self::ANY_KEY, 'listLoaderClassNameList'],
|
||||
['recordDefs', self::ANY_KEY, 'saverClassNameList'],
|
||||
|
||||
@@ -30,42 +30,29 @@
|
||||
namespace Espo\Core\Utils;
|
||||
|
||||
use Espo\Core\Api\Route as RouteItem;
|
||||
use Espo\Core\Utils\File\Manager as FileManager;
|
||||
use Espo\Core\Utils\Resource\PathProvider;
|
||||
|
||||
use Espo\Core\{
|
||||
Utils\Config,
|
||||
Utils\Metadata,
|
||||
Utils\File\Manager as FileManager,
|
||||
Utils\DataCache,
|
||||
Utils\Resource\PathProvider,
|
||||
};
|
||||
|
||||
/**
|
||||
* @phpstan-type RouteArrayShape array{
|
||||
* route: string,
|
||||
* adjustedRoute: string,
|
||||
* method: string,
|
||||
* noAuth?: bool,
|
||||
* params?: array<string, mixed>,
|
||||
* }
|
||||
*/
|
||||
class Route
|
||||
{
|
||||
/**
|
||||
* @var ?array<
|
||||
* int,
|
||||
* array{
|
||||
* route:string,
|
||||
* method:string,
|
||||
* noAuth?:bool,
|
||||
* params?:array<string,mixed>,
|
||||
* }
|
||||
* >
|
||||
*/
|
||||
/** @var ?(RouteArrayShape[]) */
|
||||
private $data = null;
|
||||
|
||||
private string $cacheKey = 'routes';
|
||||
|
||||
private string $routesFileName = 'routes.json';
|
||||
|
||||
private Config $config;
|
||||
|
||||
private Metadata $metadata;
|
||||
|
||||
private FileManager $fileManager;
|
||||
|
||||
private DataCache $dataCache;
|
||||
|
||||
private PathProvider $pathProvider;
|
||||
|
||||
public function __construct(
|
||||
@@ -100,6 +87,7 @@ class Route
|
||||
return new RouteItem(
|
||||
$item['method'],
|
||||
$item['route'],
|
||||
$item['adjustedRoute'],
|
||||
$item['params'] ?? [],
|
||||
$item['noAuth'] ?? false
|
||||
);
|
||||
@@ -113,17 +101,7 @@ class Route
|
||||
$useCache = $this->config->get('useCache');
|
||||
|
||||
if ($this->dataCache->has($this->cacheKey) && $useCache) {
|
||||
/**
|
||||
* @var ?array<
|
||||
* int,
|
||||
* array{
|
||||
* route:string,
|
||||
* method:string,
|
||||
* noAuth?:bool,
|
||||
* params?:array<string,mixed>,
|
||||
* }
|
||||
* > $data
|
||||
*/
|
||||
/** @var ?(RouteArrayShape[]) $data */
|
||||
$data = $this->dataCache->get($this->cacheKey);
|
||||
|
||||
$this->data = $data;
|
||||
@@ -139,15 +117,7 @@ class Route
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<
|
||||
* int,
|
||||
* array{
|
||||
* route:string,
|
||||
* method:string,
|
||||
* noAuth?:bool,
|
||||
* params?:array<string,mixed>,
|
||||
* }
|
||||
* >
|
||||
* @return RouteArrayShape[]
|
||||
*/
|
||||
private function unify(): array
|
||||
{
|
||||
@@ -174,24 +144,8 @@ class Route
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<
|
||||
* int,
|
||||
* array{
|
||||
* route:string,
|
||||
* method:string,
|
||||
* noAuth?:bool,
|
||||
* params?:array<string,mixed>,
|
||||
* }
|
||||
* > $currentData
|
||||
* @return array<
|
||||
* int,
|
||||
* array{
|
||||
* route:string,
|
||||
* method:string,
|
||||
* noAuth?:bool,
|
||||
* params?:array<string,mixed>,
|
||||
* }
|
||||
* >
|
||||
* @param RouteArrayShape[] $currentData
|
||||
* @return RouteArrayShape[]
|
||||
*/
|
||||
private function addDataFromFile(array $currentData, string $routeFile): array
|
||||
{
|
||||
@@ -208,38 +162,14 @@ class Route
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array<
|
||||
* int,
|
||||
* array{
|
||||
* route:string,
|
||||
* method:string,
|
||||
* noAuth?:bool,
|
||||
* conditions?: array<string,mixed>,
|
||||
* }
|
||||
* > $data
|
||||
* @param array<
|
||||
* int,
|
||||
* array{
|
||||
* route:string,
|
||||
* method:string,
|
||||
* noAuth?:bool,
|
||||
* conditions?: array<string,mixed>,
|
||||
* }
|
||||
* > $newData
|
||||
* @return array<
|
||||
* int,
|
||||
* array{
|
||||
* route:string,
|
||||
* method:string,
|
||||
* noAuth?:bool,
|
||||
* conditions?: array<string,mixed>,
|
||||
* }
|
||||
* >
|
||||
* @param RouteArrayShape[] $data
|
||||
* @param RouteArrayShape[] $newData
|
||||
* @return RouteArrayShape[]
|
||||
*/
|
||||
private function appendRoutesToData(array $data, array $newData): array
|
||||
{
|
||||
foreach ($newData as $route) {
|
||||
$route['route'] = $this->adjustPath($route['route']);
|
||||
$route['adjustedRoute'] = $this->adjustPath($route['route']);
|
||||
|
||||
if (isset($route['conditions'])) {
|
||||
$route['noAuth'] = !($route['conditions']['auth'] ?? true);
|
||||
@@ -266,7 +196,7 @@ class Route
|
||||
/** @var string $pathFormatted */
|
||||
$pathFormatted = preg_replace('/\:([a-zA-Z0-9]+)/', '{${1}}', trim($path));
|
||||
|
||||
if (substr($pathFormatted, 0, 1) !== '/') {
|
||||
if (!str_starts_with($pathFormatted, '/')) {
|
||||
return '/' . $pathFormatted;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"globalMiddlewareClassNameList": [],
|
||||
"routeMiddlewareClassNameListMap": {},
|
||||
"controllerMiddlewareClassNameListMap": {},
|
||||
"controllerActionMiddlewareClassNameListMap": {}
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
["app", "orm"],
|
||||
["app", "linkManager"],
|
||||
["app", "hook"],
|
||||
["app", "api"],
|
||||
["selectDefs"],
|
||||
["recordDefs"],
|
||||
["pdfDefs"],
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"route": "I18n",
|
||||
"route": "/I18n",
|
||||
"method": "get",
|
||||
"params": {
|
||||
"controller": "I18n"
|
||||
@@ -53,7 +53,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"route": "User/passwordChangeRequest",
|
||||
"route": "/User/passwordChangeRequest",
|
||||
"method": "post",
|
||||
"params": {
|
||||
"controller": "User",
|
||||
@@ -62,7 +62,7 @@
|
||||
"noAuth": true
|
||||
},
|
||||
{
|
||||
"route": "User/changePasswordByRequest",
|
||||
"route": "/User/changePasswordByRequest",
|
||||
"method": "post",
|
||||
"params": {
|
||||
"controller": "User",
|
||||
@@ -285,7 +285,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"route": "Oidc/authorizationData",
|
||||
"route": "/Oidc/authorizationData",
|
||||
"method": "get",
|
||||
"params": {
|
||||
"controller": "Oidc",
|
||||
@@ -294,7 +294,7 @@
|
||||
"noAuth": true
|
||||
},
|
||||
{
|
||||
"route": "Oidc/backchannelLogout",
|
||||
"route": "/Oidc/backchannelLogout",
|
||||
"method": "post",
|
||||
"params": {
|
||||
"controller": "Oidc",
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
"ext-pdo": "*",
|
||||
"psr/log": "1.1.*",
|
||||
"psr/http-message": "^1.0",
|
||||
"slim/slim": "^4.7",
|
||||
"slim/slim": "^4.11",
|
||||
"slim/psr7": "^1",
|
||||
"dragonmantank/cron-expression": "3.0.*",
|
||||
"laminas/laminas-mail": "2.20.*",
|
||||
|
||||
Generated
+23
-22
@@ -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": "0f62f7d5ae5e7936f467c5f00ef2954b",
|
||||
"content-hash": "dc3ee098594199e87884788c3461f07b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "async-aws/core",
|
||||
@@ -4036,44 +4036,45 @@
|
||||
},
|
||||
{
|
||||
"name": "slim/slim",
|
||||
"version": "4.7.1",
|
||||
"version": "4.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/slimphp/Slim.git",
|
||||
"reference": "0905e0775f8c1cfb3bbcfabeb6588dcfd8b82d3f"
|
||||
"reference": "b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/0905e0775f8c1cfb3bbcfabeb6588dcfd8b82d3f",
|
||||
"reference": "0905e0775f8c1cfb3bbcfabeb6588dcfd8b82d3f",
|
||||
"url": "https://api.github.com/repos/slimphp/Slim/zipball/b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7",
|
||||
"reference": "b0f4ca393ea037be9ac7292ba7d0a34d18bac0c7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"nikic/fast-route": "^1.3",
|
||||
"php": "^7.2 || ^8.0",
|
||||
"psr/container": "^1.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/container": "^1.0 || ^2.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
"psr/log": "^1.1"
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"adriansuter/php-autoload-override": "^1.2",
|
||||
"adriansuter/php-autoload-override": "^1.3",
|
||||
"ext-simplexml": "*",
|
||||
"guzzlehttp/psr7": "^1.7",
|
||||
"http-interop/http-factory-guzzle": "^1.0",
|
||||
"laminas/laminas-diactoros": "^2.4",
|
||||
"nyholm/psr7": "^1.3",
|
||||
"nyholm/psr7-server": "^1.0.1",
|
||||
"phpspec/prophecy": "^1.12",
|
||||
"phpstan/phpstan": "^0.12.58",
|
||||
"phpunit/phpunit": "^8.5.13",
|
||||
"guzzlehttp/psr7": "^2.4",
|
||||
"httpsoft/http-message": "^1.0",
|
||||
"httpsoft/http-server-request": "^1.0",
|
||||
"laminas/laminas-diactoros": "^2.17",
|
||||
"nyholm/psr7": "^1.5",
|
||||
"nyholm/psr7-server": "^1.0",
|
||||
"phpspec/prophecy": "^1.15",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/phpstan": "^1.8",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"slim/http": "^1.2",
|
||||
"slim/psr7": "^1.3",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"weirdan/prophecy-shim": "^1.0 || ^2.0.2"
|
||||
"slim/psr7": "^1.5",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-simplexml": "Needed to support XML format in BodyParsingMiddleware",
|
||||
@@ -4146,7 +4147,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-12-01T19:41:22+00:00"
|
||||
"time": "2022-11-06T16:33:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/async",
|
||||
@@ -7795,5 +7796,5 @@
|
||||
"ext-pdo": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.0.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user