Skip to content

Commit 06fa932

Browse files
committed
get ip address using akr middleware
1 parent afcfd84 commit 06fa932

12 files changed

Lines changed: 98 additions & 402 deletions

File tree

‎composer.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"php": "~8.5.0",
3030
"ext-curl": "*",
3131
"ext-dom": "*",
32+
"akrabat/ip-address-middleware": "^2.6",
3233
"doctrine/data-fixtures": "^2.2",
3334
"doctrine/doctrine-fixtures-bundle": "^4.3",
3435
"dotkernel/dot-cache": "^4.0",

‎config/autoload/ip-address.global.php‎

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
return [
6+
'rka' => [
7+
'ip_address' => [
8+
'check_proxy_headers' => false,
9+
'trusted_proxies' => [],
10+
'attribute_name' => 'ip_address',
11+
'headers_to_inspect' => [],
12+
],
13+
],
14+
];

‎config/config.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
\Mezzio\Router\ConfigProvider::class,
2424
\Mezzio\Router\FastRouteRouter\ConfigProvider::class,
2525
\Mezzio\Twig\ConfigProvider::class,
26+
\RKA\Middleware\Mezzio\ConfigProvider::class,
2627

2728
// Dotkernel packages
2829
\Dot\DependencyInjection\ConfigProvider::class,

‎config/pipeline.php‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Dot\ErrorHandler\ErrorHandlerInterface;
66
use Dot\ResponseHeader\Middleware\ResponseHeaderMiddleware;
7-
use Light\App\Middleware\IpAddressMiddleware;
87
use Mezzio\Application;
98
use Mezzio\Handler\NotFoundHandler;
109
use Mezzio\Helper\ServerUrlMiddleware;
@@ -14,13 +13,13 @@
1413
use Mezzio\Router\Middleware\ImplicitOptionsMiddleware;
1514
use Mezzio\Router\Middleware\MethodNotAllowedMiddleware;
1615
use Mezzio\Router\Middleware\RouteMiddleware;
16+
use RKA\Middleware\IpAddress;
1717

1818
return function (Application $app): void {
1919
// The error handler should be the first (most outer) middleware to catch
2020
// all Exceptions.
2121
$app->pipe(ErrorHandlerInterface::class);
2222
$app->pipe(ServerUrlMiddleware::class);
23-
$app->pipe(IpAddressMiddleware::class);
2423

2524
// Pipe more middleware here that you want to execute on every request:
2625
// - bootstrapping
@@ -65,6 +64,8 @@
6564
// - route-based validation
6665
// - etc.
6766

67+
$app->pipe(IpAddress::class);
68+
6869
// Register the dispatch middleware in the middleware pipeline
6970
$app->pipe(DispatchMiddleware::class);
7071

‎src/App/src/ConfigProvider.php‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
use Light\App\Handler\GetPackagesViewHandler;
3434
use Light\App\Handler\GetSitemapViewHandler;
3535
use Light\App\Handler\PostCreateContactHandler;
36-
use Light\App\Middleware\IpAddressMiddleware;
3736
use Light\App\Resolver\EntityListenerResolver;
3837
use Light\App\Service\ContactService;
3938
use Light\App\Service\FeedGenerator;
@@ -150,7 +149,6 @@ public function getDependencies(): array
150149
GetCreateContactFormHandler::class => AttributedServiceFactory::class,
151150
PostCreateContactHandler::class => AttributedServiceFactory::class,
152151
ContactService::class => AttributedServiceFactory::class,
153-
IpAddressMiddleware::class => AttributedServiceFactory::class,
154152
FeedGenerator::class => FeedGeneratorFactory::class,
155153
SitemapGenerator::class => SitemapGeneratorFactory::class,
156154
GitHubClient::class => GitHubClientFactory::class,

‎src/App/src/Handler/PostCreateContactHandler.php‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use Laminas\Diactoros\Response\HtmlResponse;
99
use Laminas\Diactoros\Response\RedirectResponse;
1010
use Light\App\Enum\ContactTopicEnum;
11-
use Light\App\Middleware\IpAddressMiddleware;
1211
use Light\App\Service\ContactService;
1312
use Mezzio\Helper\UrlHelper;
1413
use Mezzio\Template\TemplateRendererInterface;
@@ -43,13 +42,13 @@ public function handle(ServerRequestInterface $request): ResponseInterface
4342
$token = is_array($rawBody) && is_string($rawBody['cf-turnstile-response'] ?? null)
4443
? $rawBody['cf-turnstile-response']
4544
: '';
46-
$ip = $request->getAttribute(IpAddressMiddleware::ATTRIBUTE);
45+
$ip = $request->getAttribute('ip_address');
4746

48-
if (! $this->contactService->verifyTurnstile($token, is_string($ip) ? $ip : null)) {
47+
if (! $this->contactService->verifyTurnstile($token, $ip)) {
4948
$errors['captcha'] = "We couldn't verify you're human. Please try again.";
5049
}
5150

52-
if ($errors === [] && ! $this->contactService->send($data)) {
51+
if ($errors === [] && ! $this->contactService->send($data, $ip)) {
5352
$mailFailed = true;
5453
}
5554

‎src/App/src/Middleware/IpAddressMiddleware.php‎

Lines changed: 0 additions & 176 deletions
This file was deleted.

‎src/App/src/Service/ContactService.php‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ public function validate(array $data): array
176176
/**
177177
* @param ContactData $data
178178
*/
179-
public function send(array $data): bool
179+
public function send(array $data, ?string $ipAddress = null): bool
180180
{
181181
$this->mailService->getMessage()->setReplyTo($data['email'], $data['name']);
182182
$this->mailService->setSubject('New contact form submission on dotkernel.com');
183-
$this->mailService->setBody($this->buildBody($data));
183+
$this->mailService->setBody($this->buildBody($data, $ipAddress));
184184

185185
try {
186186
$result = $this->mailService->send();
@@ -237,7 +237,7 @@ private function stringValue(array $raw, string $key): string
237237
/**
238238
* @param ContactData $data
239239
*/
240-
private function buildBody(array $data): string
240+
private function buildBody(array $data, ?string $ipAddress): string
241241
{
242242
$rows = [
243243
'Topic' => ContactTopicEnum::tryFrom($data['topic'])?->label() ?? '',
@@ -247,6 +247,7 @@ private function buildBody(array $data): string
247247
'Current stack' => $data['stack'],
248248
'Message' => $data['message'],
249249
'Query params' => $data['query'],
250+
'IP address' => $ipAddress ?? '',
250251
];
251252

252253
$html = '';

‎test/Unit/App/Handler/PostCreateContactHandlerTest.php‎

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use Laminas\Diactoros\Response\RedirectResponse;
1313
use Light\App\Enum\ContactTopicEnum;
1414
use Light\App\Handler\PostCreateContactHandler;
15-
use Light\App\Middleware\IpAddressMiddleware;
1615
use Light\App\Service\ContactService;
1716
use Mezzio\Helper\UrlHelper;
1817
use Mezzio\Template\TemplateRendererInterface;
@@ -198,7 +197,7 @@ public function testFailedTurnstileRerendersWithCaptchaErrorAndSendsNothing(): v
198197

199198
$request = $this->createStub(ServerRequestInterface::class);
200199
$request->method('getParsedBody')->willReturn($data);
201-
$request->method('getAttribute')->willReturnMap([[IpAddressMiddleware::ATTRIBUTE, null, '203.0.113.5']]);
200+
$request->method('getAttribute')->willReturnMap([['ip_address', null, '203.0.113.5']]);
202201

203202
$contactService = $this->createMock(ContactService::class);
204203
$contactService->method('normalize')->willReturn([
@@ -239,4 +238,43 @@ public function testFailedTurnstileRerendersWithCaptchaErrorAndSendsNothing(): v
239238
$this->assertInstanceOf(HtmlResponse::class, $response);
240239
$this->assertSame(200, $response->getStatusCode());
241240
}
241+
242+
/**
243+
* @throws Exception
244+
*/
245+
public function testValidSubmissionSendsTheIpAddressFromTheRequestAttribute(): void
246+
{
247+
$request = $this->createStub(ServerRequestInterface::class);
248+
$request->method('getParsedBody')->willReturn($this->validData());
249+
$request->method('getAttribute')->willReturnMap([['ip_address', null, '203.0.113.5']]);
250+
251+
$contactService = $this->createMock(ContactService::class);
252+
$contactService->method('normalize')->willReturn([
253+
'topic' => 'migration',
254+
'name' => 'Jane Doe',
255+
'email' => 'jane@example.com',
256+
'company' => 'Acme Inc',
257+
'stack' => 'ZF3, PHP 7.4',
258+
'message' => 'We would like to talk about migrating our platform.',
259+
'query' => '',
260+
]);
261+
$contactService->method('validate')->willReturn([]);
262+
$contactService->method('verifyTurnstile')->willReturn(true);
263+
$contactService
264+
->expects($this->once())
265+
->method('send')
266+
->with($this->anything(), '203.0.113.5')
267+
->willReturn(true);
268+
269+
$urlHelper = $this->createStub(UrlHelper::class);
270+
$urlHelper->method('generate')->willReturn('/contact/?contact=sent#contact-form');
271+
272+
$response = (new PostCreateContactHandler(
273+
$this->createStub(TemplateRendererInterface::class),
274+
$urlHelper,
275+
$contactService
276+
))->handle($request);
277+
278+
$this->assertInstanceOf(RedirectResponse::class, $response);
279+
}
242280
}

0 commit comments

Comments
 (0)