From e14256326e246c8bae37fd5d063417150040d4d3 Mon Sep 17 00:00:00 2001
From: Chris Page
Date: Mon, 4 Nov 2024 21:05:06 +0000
Subject: [PATCH] Added WithoutPan middleware
---
README.md | 11 ++++++++
.../Middleware/InjectJavascriptLibrary.php | 14 ++++++++++-
.../Laravel/Http/Middleware/WithoutPan.php | 17 +++++++++++++
.../InjectJavascriptLibraryTest.php | 25 +++++++++++++++++++
4 files changed, 66 insertions(+), 1 deletion(-)
create mode 100644 src/Adapters/Laravel/Http/Middleware/WithoutPan.php
diff --git a/README.md b/README.md
index 5b3a467..f4517a6 100644
--- a/README.md
+++ b/README.md
@@ -117,6 +117,17 @@ To flush your product analytics, you may use the `pan:flush` Artisan command:
php artisan pan:flush
```
+## Exclude injection for certain routes
+
+If you want to exclude injection on certain routes of your application, you can
+use the `Pan\Adapters\Laravel\Http\Middleware\WithoutPan` middleware:
+
+```php
+Route::get('/no-pan', function () {
+ return view('no-pan');
+})->middleware(WithoutPan::class);
+```
+
## How does it work?
Via middleware, Pan injects a simple JavaScript library into your HTML pages. This library listens to events like `viewed`, `clicked`, or `hovered` and sends the data to your Laravel application. Note that this library does not collect any personal information; such as IP addresses, user agents, or any information that could be used to identify a user.
diff --git a/src/Adapters/Laravel/Http/Middleware/InjectJavascriptLibrary.php b/src/Adapters/Laravel/Http/Middleware/InjectJavascriptLibrary.php
index a3e8f93..73288d3 100644
--- a/src/Adapters/Laravel/Http/Middleware/InjectJavascriptLibrary.php
+++ b/src/Adapters/Laravel/Http/Middleware/InjectJavascriptLibrary.php
@@ -6,6 +6,7 @@
use Closure;
use Illuminate\Http\Request;
+use Illuminate\Routing\Route;
use Illuminate\Support\Facades\File;
use Pan\PanConfiguration;
use Symfony\Component\HttpFoundation\Response;
@@ -32,6 +33,16 @@ public function handle(Request $request, Closure $next): Response
{
/** @var Response $response */
$response = $next($request);
+ $route = $request->route();
+
+ if ($route instanceof Route) {
+ /** @var string[] $middleware */
+ $middleware = $route->middleware(null);
+
+ if (in_array(WithoutPan::class, $middleware)) {
+ return $response;
+ }
+ }
if ($response->headers->get('Content-Type') === 'text/html; charset=UTF-8') {
$content = (string) $response->getContent();
@@ -58,7 +69,8 @@ private function inject(Response $response): void
$response->setContent(
str_replace(
'
+ Welcome to my app
+ ',
- sprintf(<<<'HTML'
+ sprintf(
+ <<<'HTML'
diff --git a/src/Adapters/Laravel/Http/Middleware/WithoutPan.php b/src/Adapters/Laravel/Http/Middleware/WithoutPan.php
new file mode 100644
index 0000000..c978621
--- /dev/null
+++ b/src/Adapters/Laravel/Http/Middleware/WithoutPan.php
@@ -0,0 +1,17 @@
+ <<<'HTML'
@@ -24,6 +25,30 @@
->assertSee('_TEST_CSRF_TOKEN_');
});
+it('does not inject the javascript library when the exclusion middleware is set', function (): void {
+
+ Route::get('/', fn (): string => <<<'HTML'
+
+