From da4bdc6bf41113774c8b734bc00a6d4fc7ca42c5 Mon Sep 17 00:00:00 2001 From: Roberto Date: Thu, 4 Jun 2026 00:30:44 +0200 Subject: [PATCH] Add proxy IP headers to Telegram notifications --- app/Http/Controllers/FrontendController.php | 22 +++++++++-- .../NotifyTelegramAboutContactMessage.php | 17 +++++++-- app/Jobs/NotifyTelegramAboutPageVisit.php | 6 ++- .../NotifyTelegramAboutPersonaliaClick.php | 7 +++- app/Services/TelegramNotificationService.php | 37 +++++++++++++++++-- .../TelegramNotificationServiceTest.php | 26 ++++++++++--- 6 files changed, 96 insertions(+), 19 deletions(-) diff --git a/app/Http/Controllers/FrontendController.php b/app/Http/Controllers/FrontendController.php index 5f2eb40..b917b61 100644 --- a/app/Http/Controllers/FrontendController.php +++ b/app/Http/Controllers/FrontendController.php @@ -32,7 +32,8 @@ class FrontendController extends Controller NotifyTelegramAboutPersonaliaClick::dispatch( $personalia, request()->ip(), - request()->userAgent() + request()->userAgent(), + $this->ipHeaders(request()) ); return response()->json([ @@ -55,7 +56,8 @@ class FrontendController extends Controller $request->ip(), $request->userAgent(), $validated['email'] ?? null, - $validated['phone'] ?? null + $validated['phone'] ?? null, + $this->ipHeaders($request) ); return response()->json(['status' => 'success']); @@ -67,9 +69,23 @@ class FrontendController extends Controller $request->validated(), $request->ip(), $request->userAgent(), - $request->header('Accept-Language') + $request->header('Accept-Language'), + $this->ipHeaders($request) ); return response()->json(['status' => 'queued']); } + + /** + * @return array + */ + protected function ipHeaders(Request $request): array + { + return [ + 'CF-Connecting-IP' => $request->header('CF-Connecting-IP'), + 'X-Forwarded-For' => $request->header('X-Forwarded-For'), + 'X-Real-IP' => $request->header('X-Real-IP'), + 'Forwarded' => $request->header('Forwarded'), + ]; + } } diff --git a/app/Jobs/NotifyTelegramAboutContactMessage.php b/app/Jobs/NotifyTelegramAboutContactMessage.php index 20988ee..5e3f7fb 100644 --- a/app/Jobs/NotifyTelegramAboutContactMessage.php +++ b/app/Jobs/NotifyTelegramAboutContactMessage.php @@ -25,8 +25,18 @@ class NotifyTelegramAboutContactMessage implements ShouldQueue protected ?string $phone; - public function __construct(string $name, string $message, string $ip, string $userAgent, ?string $email = null, ?string $phone = null) - { + /** + * @param array $ipHeaders + */ + public function __construct( + string $name, + string $message, + string $ip, + string $userAgent, + ?string $email = null, + ?string $phone = null, + protected array $ipHeaders = [] + ) { $this->name = $name; $this->message = $message; $this->ip = $ip; @@ -43,7 +53,8 @@ class NotifyTelegramAboutContactMessage implements ShouldQueue $this->ip, $this->userAgent, $this->email, - $this->phone + $this->phone, + $this->ipHeaders ); } } diff --git a/app/Jobs/NotifyTelegramAboutPageVisit.php b/app/Jobs/NotifyTelegramAboutPageVisit.php index 8e0ae96..c62fcfa 100644 --- a/app/Jobs/NotifyTelegramAboutPageVisit.php +++ b/app/Jobs/NotifyTelegramAboutPageVisit.php @@ -15,16 +15,18 @@ class NotifyTelegramAboutPageVisit implements ShouldQueue /** * @param array $visit + * @param array $ipHeaders */ public function __construct( protected array $visit, protected ?string $ip, protected ?string $userAgent, - protected ?string $acceptLanguage + protected ?string $acceptLanguage, + protected array $ipHeaders = [] ) {} public function handle(TelegramNotificationService $telegram): void { - $telegram->notifyPageVisit($this->visit, $this->ip, $this->userAgent, $this->acceptLanguage); + $telegram->notifyPageVisit($this->visit, $this->ip, $this->userAgent, $this->acceptLanguage, $this->ipHeaders); } } diff --git a/app/Jobs/NotifyTelegramAboutPersonaliaClick.php b/app/Jobs/NotifyTelegramAboutPersonaliaClick.php index 4b8e18f..fa375d8 100644 --- a/app/Jobs/NotifyTelegramAboutPersonaliaClick.php +++ b/app/Jobs/NotifyTelegramAboutPersonaliaClick.php @@ -20,7 +20,10 @@ class NotifyTelegramAboutPersonaliaClick implements ShouldQueue protected ?string $userAgent; - public function __construct(Personalia $personalia, ?string $ip, ?string $userAgent) + /** + * @param array $ipHeaders + */ + public function __construct(Personalia $personalia, ?string $ip, ?string $userAgent, protected array $ipHeaders = []) { $this->personalia = $personalia; $this->ip = $ip; @@ -29,6 +32,6 @@ class NotifyTelegramAboutPersonaliaClick implements ShouldQueue public function handle(TelegramNotificationService $telegram): void { - $telegram->notifyPersonaliaClick($this->personalia, $this->ip, $this->userAgent); + $telegram->notifyPersonaliaClick($this->personalia, $this->ip, $this->userAgent, $this->ipHeaders); } } diff --git a/app/Services/TelegramNotificationService.php b/app/Services/TelegramNotificationService.php index c7f9204..a3ce927 100644 --- a/app/Services/TelegramNotificationService.php +++ b/app/Services/TelegramNotificationService.php @@ -7,16 +7,21 @@ use Illuminate\Support\Facades\Http; class TelegramNotificationService { + /** + * @param array $ipHeaders + */ public function notifyContactMessage( string $name, string $message, string $ip, string $userAgent, ?string $email = null, - ?string $phone = null + ?string $phone = null, + array $ipHeaders = [] ): void { $email ??= '-'; $phone ??= '-'; + $ipHeaderText = $this->formatIpHeaders($ipHeaders); $text = <<send($text); } - public function notifyPersonaliaClick(Personalia $personalia, ?string $ip, ?string $userAgent): void + /** + * @param array $ipHeaders + */ + public function notifyPersonaliaClick(Personalia $personalia, ?string $ip, ?string $userAgent, array $ipHeaders = []): void { $ip ??= '-'; $userAgent ??= '-'; + $ipHeaderText = $this->formatIpHeaders($ipHeaders); $message = <<value} IP: {$ip} +{$ipHeaderText} User Agent: {$userAgent} Tijdstip: {now()->format('d-m-Y H:i')} @@ -56,11 +67,13 @@ TEXT; /** * @param array $visit + * @param array $ipHeaders */ - public function notifyPageVisit(array $visit, ?string $ip, ?string $userAgent, ?string $acceptLanguage): void + public function notifyPageVisit(array $visit, ?string $ip, ?string $userAgent, ?string $acceptLanguage, array $ipHeaders = []): void { $screen = $this->formatDimensions($visit['screen'] ?? null); $viewport = $this->formatDimensions($visit['viewport'] ?? null); + $ipHeaderText = $this->formatIpHeaders($ipHeaders); $message = <<value($visit['referrer'] ?? null)} Visitor ID: {$this->value($visit['visitor_id'] ?? null)} IP: {$this->value($ip)} +{$ipHeaderText} User Agent: {$this->value($userAgent)} Accept-Language: {$this->value($acceptLanguage)} Browser taal: {$this->value($visit['language'] ?? null)} @@ -108,6 +122,23 @@ TEXT; ]); } + /** + * @param array $ipHeaders + */ + protected function formatIpHeaders(array $ipHeaders): string + { + $headers = [ + 'CF-Connecting-IP', + 'X-Forwarded-For', + 'X-Real-IP', + 'Forwarded', + ]; + + return collect($headers) + ->map(fn (string $header): string => "{$header}: {$this->value($ipHeaders[$header] ?? null)}") + ->implode("\n"); + } + protected function value(mixed $value): string { if (is_bool($value)) { diff --git a/tests/Feature/TelegramNotificationServiceTest.php b/tests/Feature/TelegramNotificationServiceTest.php index 5d8c6b3..7dadbbc 100644 --- a/tests/Feature/TelegramNotificationServiceTest.php +++ b/tests/Feature/TelegramNotificationServiceTest.php @@ -18,13 +18,19 @@ test('telegram service sends a contact message notification', function () { ip: '127.0.0.1', userAgent: 'Pest Browser', email: 'roberto@example.com', - phone: '+31612345678' + phone: '+31612345678', + ipHeaders: [ + 'CF-Connecting-IP' => '203.0.113.10', + 'X-Forwarded-For' => '203.0.113.10, 198.51.100.20', + ], ); Http::assertSent(fn ($request) => $request->url() === 'https://api.telegram.org/bottelegram-token/sendMessage' && $request['chat_id'] === 'telegram-chat' && str_contains($request['text'], 'Nieuw contactbericht ontvangen') - && str_contains($request['text'], 'roberto@example.com')); + && str_contains($request['text'], 'roberto@example.com') + && str_contains($request['text'], 'CF-Connecting-IP: 203.0.113.10') + && str_contains($request['text'], 'X-Forwarded-For: 203.0.113.10, 198.51.100.20')); }); test('telegram service sends a personalia click notification', function () { @@ -39,10 +45,13 @@ test('telegram service sends a personalia click notification', function () { 'value' => 'roberto@example.com', ]); - app(TelegramNotificationService::class)->notifyPersonaliaClick($personalia, '127.0.0.1', 'Pest Browser'); + app(TelegramNotificationService::class)->notifyPersonaliaClick($personalia, '127.0.0.1', 'Pest Browser', [ + 'CF-Connecting-IP' => '203.0.113.10', + ]); Http::assertSent(fn ($request) => str_contains($request['text'], 'Persoonlijke gegevens bekeken') - && str_contains($request['text'], 'roberto@example.com')); + && str_contains($request['text'], 'roberto@example.com') + && str_contains($request['text'], 'CF-Connecting-IP: 203.0.113.10')); }); test('telegram service sends a page visit notification', function () { @@ -69,10 +78,15 @@ test('telegram service sends a page visit notification', function () { 'width' => 1440, 'height' => 900, ], - ], '127.0.0.1', 'Pest Browser', 'nl-NL,nl;q=0.9'); + ], '127.0.0.1', 'Pest Browser', 'nl-NL,nl;q=0.9', [ + 'CF-Connecting-IP' => '203.0.113.10', + 'X-Real-IP' => '198.51.100.30', + ]); Http::assertSent(fn ($request) => str_contains($request['text'], 'Pagina bezocht') && str_contains($request['text'], 'Visitor ID: visitor-123') && str_contains($request['text'], 'Scherm: 1920x1080') - && str_contains($request['text'], 'Viewport: 1440x900')); + && str_contains($request['text'], 'Viewport: 1440x900') + && str_contains($request['text'], 'CF-Connecting-IP: 203.0.113.10') + && str_contains($request['text'], 'X-Real-IP: 198.51.100.30')); });