Skip to content

Commit

Permalink
Release prep 1.8.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Willem Poortman committed Jul 4, 2023
1 parent 976c00b commit 56d1aca
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 5 deletions.
63 changes: 58 additions & 5 deletions src/Controller/Post/Livewire.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Magento\Framework\Exception\NotFoundException;
use Magento\Framework\View\Element\Template;
use Magewirephp\Magewire\Helper\Security as SecurityHelper;
use Magewirephp\Magewire\Model\Request\MagewireSubsequentActionInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Magento\Framework\App\Action\HttpPostActionInterface;
Expand All @@ -31,7 +32,7 @@
use Magewirephp\Magewire\Model\HttpFactory;
use Symfony\Component\HttpKernel\Exception\HttpException;

class Livewire implements HttpPostActionInterface, CsrfAwareActionInterface
class Livewire implements HttpPostActionInterface, CsrfAwareActionInterface, MagewireSubsequentActionInterface
{
public const HANDLE = 'magewire_post_livewire';

Expand All @@ -45,6 +46,17 @@ class Livewire implements HttpPostActionInterface, CsrfAwareActionInterface
protected RequestInterface $request;
protected LoggerInterface $logger;

/**
* @param JsonFactory $resultJsonFactory
* @param ComponentHelper $componentHelper
* @param PageFactory $resultPageFactory
* @param SerializerInterface $serializer
* @param HttpFactory $httpFactory
* @param EventManagerInterface $eventManager
* @param SecurityHelper $securityHelper
* @param RequestInterface $request
* @param LoggerInterface $logger
*/
public function __construct(
JsonFactory $resultJsonFactory,
ComponentHelper $componentHelper,
Expand All @@ -67,14 +79,16 @@ public function __construct(
$this->logger = $logger;
}

/**
* @return Json
*/
public function execute(): Json
{
$result = $this->resultJsonFactory->create();

try {
$this->validateForUpdateRequest();
$post = $this->request->getParams();

$post = $this->serializer->unserialize(file_get_contents('php://input'));
/** @var Template $block */
$block = $this->locateWireComponent($post);

Expand Down Expand Up @@ -118,6 +132,8 @@ public function execute(): Json
}

/**
* @param array $post
* @return BlockInterface
* @throws NotFoundException
*/
public function locateWireComponent(array $post): BlockInterface
Expand All @@ -140,14 +156,48 @@ public function locateWireComponent(array $post): BlockInterface
return $block;
}

public function throwException(Exception $exception): Json
{
$result = $this->resultJsonFactory->create();
$statuses = $this->getHttpResponseStatuses();

$code = $exception instanceof HttpException ? $exception->getStatusCode() : $exception->getCode();
$message = empty($exception->getMessage()) ? ($statuses[$code] ?? 'Something went wrong') : $exception->getMessage();

// Make an exception for optional outsiders.
$code = in_array($code, [0, -1], true) ? Response::HTTP_INTERNAL_SERVER_ERROR : $code;
// Try and grep the status from the available stack or get 500 when it's unavailable.
$code = $statuses[$code] ? $code : Response::HTTP_INTERNAL_SERVER_ERROR;
// Set the status header with the returned code and belonging response phrase.
$result->setStatusHeader($code, AbstractMessage::VERSION_11, $statuses[$code]);

if ($code === 500) {
$this->logger->critical($exception->getMessage());
}

return $result->setData([
'message' => $message,
'code' => $code
]);
}

/**
* @inheritDoc
*/
public function createCsrfValidationException(RequestInterface $request): ?InvalidRequestException
{
return null;
$message = 'Session expired. Please refresh and try again.';
$result = $this->throwException(new HttpException(419, $message));

return new InvalidRequestException($result, [new Phrase($message)]);
}

/**
* @inheritDoc
*/
public function validateForCsrf(RequestInterface $request): bool
{
return true;
return $this->securityHelper->validateFormKey($this->request);
}

/**
Expand All @@ -160,6 +210,9 @@ public function validateForUpdateRequest(): void
}
}

/**
* @return array
*/
public function getHttpResponseStatuses(): array
{
$statuses = Response::$statusTexts;
Expand Down
19 changes: 19 additions & 0 deletions src/Model/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,32 @@

class Request implements RequestInterface
{
public $message;
public $fingerprint;
public $memo;
public $meta;
public $updates;

protected bool $isSubsequent = false;
protected bool $isRefreshing = false;

/**
* @inheritdoc
*/
public function getMessage(): string
{
return $this->message;
}

/**
* @inheritdoc
*/
public function setMessage(string $message): \Magewirephp\Magewire\Model\RequestInterface
{
$this->message = $message;
return $this;
}

/**
* @inheritdoc
*/
Expand Down
18 changes: 18 additions & 0 deletions src/Model/Request/MagewireSubsequentActionInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
/**
* Copyright © Willem Poortman 2021-present. All rights reserved.
*
* Please read the README and LICENSE files for more
* details on copyrights and license information.
*/

namespace Magewirephp\Magewire\Model\Request;

/**
* Marker for actions processing a subsequent Magewire POST requests.
*
* @api
*/
interface MagewireSubsequentActionInterface
{
}
57 changes: 57 additions & 0 deletions src/Model/Request/MagewireValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

declare(strict_types=1);

namespace Magewirephp\Magewire\Model\Request;

use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\Request\InvalidRequestException;
use Magento\Framework\App\Request\ValidatorInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Phrase;
use Magento\Framework\Serialize\SerializerInterface;

class MagewireValidator implements ValidatorInterface
{
protected SerializerInterface $serializer;
protected JsonFactory $resultJsonFactory;

public function __construct(
SerializerInterface $serializer,
JsonFactory $resultJsonFactory
) {
$this->serializer = $serializer;
$this->resultJsonFactory = $resultJsonFactory;
}

public function validate(RequestInterface $request, ActionInterface $action): void
{
if (! $action instanceof MagewireSubsequentActionInterface) {
return;
}

$input = $this->serializer->unserialize(file_get_contents('php://input'));
$handle = $input['fingerprint']['handle'] ?? null;

if (! $handle || preg_match('/^[a-zA-Z0-9][a-zA-Z\d\-_\.]*$/', $handle) !== 1) {
$message = 'Bad Request';

$result = $this->resultJsonFactory->create();
$result->setStatusHeader(400);

$result->setData([
'message'=> $message,
'code' => 400
]);

throw new InvalidRequestException($result, [new Phrase($message)]);
}

$request->setParams($input);
}
}
11 changes: 11 additions & 0 deletions src/Model/RequestInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@
*/
interface RequestInterface
{
/**
* @return string
*/
public function getMessage(): string;

/**
* @param $fingerprint
* @return \Magewirephp\Magewire\Model\RequestInterface
*/
public function setMessage(string $message): \Magewirephp\Magewire\Model\RequestInterface;

/**
* string $index
* @return mixed
Expand Down
8 changes: 8 additions & 0 deletions src/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,12 @@
type="Magewirephp\Magewire\Model\Request"/>
<preference for="Magewirephp\Magewire\Model\ResponseInterface"
type="Magewirephp\Magewire\Model\Response"/>

<type name="Magento\Framework\App\Request\CompositeValidator">
<arguments>
<argument name="validators" xsi:type="array">
<item name="magewire_validator" xsi:type="object">Magewirephp\Magewire\Model\Request\MagewireValidator</item>
</argument>
</arguments>
</type>
</config>

0 comments on commit 56d1aca

Please sign in to comment.