Skip to content

Commit

Permalink
feat: support multiple configurations
Browse files Browse the repository at this point in the history
  • Loading branch information
kenjis committed Mar 24, 2024
1 parent 5e93acd commit 86ee415
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 151 deletions.
161 changes: 83 additions & 78 deletions app/Config/Cors.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,89 +12,94 @@
class Cors extends BaseConfig
{
/**
* Origins for the `Access-Control-Allow-Origin` header.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*
* E.g.:
* - ['http://localhost:8080']
* - ['https://www.example.com']
*
* @var list<string>
* The default CORS configuration.
*
* @var array{
* allowedOrigins: list<string>,
* allowedOriginsPatterns: list<string>,
* supportsCredentials: bool,
* allowedHeaders: list<string>,
* exposedHeaders: list<string>,
* allowedMethods: list<string>,
* maxAge: int,
* }
*/
public array $allowedOrigins = [];
public array $default = [
/**
* Origins for the `Access-Control-Allow-Origin` header.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*
* E.g.:
* - ['http://localhost:8080']
* - ['https://www.example.com']
*/
'allowedOrigins' => [],

/**
* Origin regex patterns for the `Access-Control-Allow-Origin` header.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*
* NOTE: A pattern specified here is part of a regular expression. It will
* be actually `#\A<pattern>\z#`.
*
* E.g.:
* - ['https://\w+\.example\.com']
*
* @var list<string>
*/
public array $allowedOriginsPatterns = [];
/**
* Origin regex patterns for the `Access-Control-Allow-Origin` header.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
*
* NOTE: A pattern specified here is part of a regular expression. It will
* be actually `#\A<pattern>\z#`.
*
* E.g.:
* - ['https://\w+\.example\.com']
*/
'allowedOriginsPatterns' => [],

/**
* Weather to send the `Access-Control-Allow-Credentials` header.
*
* The Access-Control-Allow-Credentials response header tells browsers whether
* the server allows cross-origin HTTP requests to include credentials.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
*/
public bool $supportsCredentials = false;
/**
* Weather to send the `Access-Control-Allow-Credentials` header.
*
* The Access-Control-Allow-Credentials response header tells browsers whether
* the server allows cross-origin HTTP requests to include credentials.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
*/
'supportsCredentials' => false,

/**
* Set headers to allow.
*
* The Access-Control-Allow-Headers response header is used in response to
* a preflight request which includes the Access-Control-Request-Headers to
* indicate which HTTP headers can be used during the actual request.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
*
* @var list<string>
*/
public array $allowedHeaders = [];
/**
* Set headers to allow.
*
* The Access-Control-Allow-Headers response header is used in response to
* a preflight request which includes the Access-Control-Request-Headers to
* indicate which HTTP headers can be used during the actual request.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
*/
'allowedHeaders' => [],

/**
* Set headers to expose.
*
* The Access-Control-Expose-Headers response header allows a server to
* indicate which response headers should be made available to scripts running
* in the browser, in response to a cross-origin request.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
*
* @var list<string>
*/
public array $exposedHeaders = [];
/**
* Set headers to expose.
*
* The Access-Control-Expose-Headers response header allows a server to
* indicate which response headers should be made available to scripts running
* in the browser, in response to a cross-origin request.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
*/
'exposedHeaders' => [],

/**
* Set methods to allow.
*
* The Access-Control-Allow-Methods response header specifies one or more
* methods allowed when accessing a resource in response to a preflight
* request.
*
* E.g.:
* - ['GET', 'POST', 'PUT', 'DELETE']
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
*
* @var list<string>
*/
public array $allowedMethods = [];
/**
* Set methods to allow.
*
* The Access-Control-Allow-Methods response header specifies one or more
* methods allowed when accessing a resource in response to a preflight
* request.
*
* E.g.:
* - ['GET', 'POST', 'PUT', 'DELETE']
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
*/
'allowedMethods' => [],

/**
* Set how many seconds the results of a preflight request can be cached.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
*/
public int $maxAge = 7200;
/**
* Set how many seconds the results of a preflight request can be cached.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age
*/
'maxAge' => 7200,
];
}
27 changes: 22 additions & 5 deletions system/Filters/Cors.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
*/
class Cors implements FilterInterface
{
private CorsService $cors;
private ?CorsService $cors = null;

/**
* @testTag $config is used for testing purposes only.
*
* @param array{
* allowedOrigins?: list<string>,
* allowedOriginsPatterns?: list<string>,
Expand All @@ -38,20 +40,24 @@ class Cors implements FilterInterface
*/
public function __construct(array $config = [])
{
$this->cors = new CorsService($config);
if ($config !== []) {
$this->cors = new CorsService($config);
}
}

/**
* @param array<string, list<string>>|null $arguments
* @param list<string>|null $arguments
*
* @return RequestInterface|ResponseInterface|string|void
* @return ResponseInterface|string|void
*/
public function before(RequestInterface $request, $arguments = null)
{
if (! $request instanceof IncomingRequest) {
return;
}

$this->createCorsService($arguments);

/** @var ResponseInterface $response */
$response = service('response');

Expand All @@ -61,7 +67,16 @@ public function before(RequestInterface $request, $arguments = null)
}

/**
* @param array<string, list<string>>|null $arguments
* @param list<string>|null $arguments
*/
private function createCorsService(?array $arguments): void
{
$this->cors ??= ($arguments === null) ? CorsService::factory()
: CorsService::factory($arguments[0]);
}

/**
* @param list<string>|null $arguments
*
* @return ResponseInterface|void
*/
Expand All @@ -71,6 +86,8 @@ public function after(RequestInterface $request, ResponseInterface $response, $a
return;
}

$this->createCorsService($arguments);

return $this->cors->addResponseHeaders($request, $response);
}
}
12 changes: 11 additions & 1 deletion system/HTTP/Cors.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,21 @@ public function __construct($config = null)
{
$config ??= config(CorsConfig::class);
if ($config instanceof CorsConfig) {
$config = (array) $config;
$config = $config->default;
}
$this->config = array_merge($this->config, $config);
}

/**
* Creates a new instance by config name.
*/
public static function factory(string $configName = 'default'): self
{
$config = config(CorsConfig::class)->{$configName};

return new self($config);
}

public function isPreflightRequest(IncomingRequest $request): bool
{
return $request->is('OPTIONS')
Expand Down
Loading

0 comments on commit 86ee415

Please sign in to comment.