Skip to content

Commit

Permalink
chore: merge staging into master #1059
Browse files Browse the repository at this point in the history
  • Loading branch information
ItsANameToo authored May 3, 2022
2 parents c0d10c7 + 4c9d17a commit e9ee6cc
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 3 deletions.
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ All notable changes to this project will be documented in this file.

## [Unreleased Devnet](https://github.com/ArkEcosystem/explorer/compare/staging...develop)

## 2022-05-02 (Explorer + Dexplorer)

### Fixed

- use livewire middleware directly in project ([#1057]) (b7cbeec1, @ItsANameToo)
- mobile voter weight ([#1056]) (a06d486a, @alexbarnsley)

---

## 2022-03-29 (Explorer + Dexplorer)

### Changed
Expand Down Expand Up @@ -408,4 +417,6 @@ All notable changes to this project will be documented in this file.
[#1047]: https://github.com/Arkecosystem/explorer/pull/1047
[#1049]: https://github.com/Arkecosystem/explorer/pull/1049
[#1048]: https://github.com/Arkecosystem/explorer/pull/1048
[#1052]: https://github.com/Arkecosystem/explorer/pull/1052
[#1052]: https://github.com/Arkecosystem/explorer/pull/1052
[#1057]: https://github.com/Arkecosystem/explorer/pull/1057
[#1056]: https://github.com/Arkecosystem/explorer/pull/1056
2 changes: 1 addition & 1 deletion app/Http/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
namespace App\Http;

use App\Http\Middleware\Authenticate;
use App\Http\Middleware\DropInvalidLivewireRequests;
use App\Http\Middleware\EncryptCookies;
use App\Http\Middleware\PreventRequestsDuringMaintenance;
use App\Http\Middleware\RedirectIfAuthenticated;
use App\Http\Middleware\SubstituteBindings;
use App\Http\Middleware\TrimStrings;
use App\Http\Middleware\TrustProxies;
use App\Http\Middleware\VerifyCsrfToken;
use ARKEcosystem\Foundation\UserInterface\Http\Middlewares\DropInvalidLivewireRequests;
use Fruitcake\Cors\HandleCors;
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
use Illuminate\Auth\Middleware\Authorize;
Expand Down
130 changes: 130 additions & 0 deletions app/Http/Middleware/DropInvalidLivewireRequests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

declare(strict_types=1);

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Livewire\Exceptions\ComponentNotFoundException;
use Livewire\Livewire;

final class DropInvalidLivewireRequests
{
public function handle(Request $request, Closure $next): mixed
{
if (! $request->routeIs('livewire.*')) {
return $next($request);
}

if ($this->hasValidSignature($request)) {
return $next($request);
}

if (! $this->containsValidPayload($request)) {
// Throwing 404 Not Found for some reason doesn't work as Livewire doesn't know how to intercept the 404,
// as it actually expects a response.(I guess as this wasn't working before with 404).
// If 403 is thrown, Livewire knows to actually throw back 403 to browser.
abort(403);
}

if (! $this->isValidComponent($request->input('fingerprint.name'))) {
abort(403);
}

if ($this->fireableEvents($request)->isNotEmpty()) {
$this->ensureAllFireableEventsAreValid($request);
}

return $next($request);
}

/**
* The file upload request on Livewire doesn't contain `fingerprint` or
* `serverMemo` but a signed URL instead that we can validate using the
* built-in `hasValidSignature` method.
* (`/livewire/upload-file?expires={timestamp}&signature={signature}`).
*
* @param \Illuminate\Http\Request $request
*
* @return bool
*/
private function hasValidSignature(Request $request) : bool
{
if ($request->filled('signature')) {
// @phpstan-ignore-next-line
return $request->hasValidSignature();
}

return false;
}

/**
* We want to drop all Livewire requests that want to manipulate on a component that doesn't even exist.
*
* @param string $component
*
* @return bool
*/
private function isValidComponent(string $component) : bool
{
try {
return Livewire::getClass($component) !== null;
} catch (ComponentNotFoundException $e) {
return false;
}
}

/**
* A valid Livewire request should contain fingerprint data (ID, method) and stuff like checksum.
*
* @param \Illuminate\Http\Request $request
*
* @return bool
*/
private function containsValidPayload(Request $request) : bool
{
return $request->filled(['fingerprint.id', 'fingerprint.method', 'fingerprint.name', 'fingerprint.path'])
&& $request->filled(['serverMemo.checksum', 'serverMemo.htmlHash']);
}

/**
* Ensure all events that the request fires actually exist for the Livewire component.
* If there are some events that want to be fired and they don't exist on the component,
* we want to respond with 403.
*
* @param Request $request
* @return void
*/
private function ensureAllFireableEventsAreValid(Request $request) : void
{
try {
$component = Livewire::getInstance(
$request->input('fingerprint.name'),
$request->input('fingerprint.id')
);
} catch (ComponentNotFoundException $e) {
abort(403);
}

abort_if($this->fireableEvents($request)->diff(
$component->getEventsBeingListenedFor()
)->isNotEmpty(), 403);
}

/**
* Get all of the events that the request wants to fire for the Livewire component.
*
* @param Request $request
* @return Collection
*/
private function fireableEvents(Request $request) : Collection
{
return $request->collect('updates')
->filter(fn (array $update) => ($update['type'] ?? '') === 'fireEvent')
->pluck('payload.event')
->unique()
->values();
}
}
2 changes: 1 addition & 1 deletion resources/views/livewire/wallet-voter-table.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<x-skeletons.wallets>
<x-tables.desktop.wallets :wallets="$wallets" without-truncate use-vote-weight />

<x-tables.mobile.wallets :wallets="$wallets" />
<x-tables.mobile.wallets :wallets="$wallets" use-vote-weight />

<x-general.pagination :results="$wallets" class="mt-8" />

Expand Down

0 comments on commit e9ee6cc

Please sign in to comment.