From 183233172ccf1ba464998ffbd831dcc699f6d43c Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 27 Jun 2025 12:24:02 +0200 Subject: [PATCH 01/22] add config vars for sending complaint mails --- config/app.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/app.php b/config/app.php index e2cce9376..52b70f6cc 100644 --- a/config/app.php +++ b/config/app.php @@ -10,6 +10,9 @@ 'contact-mail-recipient' => env('WBSTACK_CONTACT_MAIL_RECIPIENT', 'wikibase-cloud-owner@lists.wikimedia.org'), 'contact-mail-sender' => env('WBSTACK_CONTACT_MAIL_SENDER', 'contact-@wikibase.cloud'), + 'complaint-mail-recipient' => env('WBSTACK_COMPLAINT_MAIL_RECIPIENT', 'dsa-meldung@wikimedia.de'), + 'complaint-mail-sender' => env('WBSTACK_COMPLAINT_MAIL_SENDER', 'dsa@wikibase.cloud'), + /* |-------------------------------------------------------------------------- | Application Name From 1d6fabaa2a0d2a545bac5f662c08d62c0dd6ea86 Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 27 Jun 2025 12:24:20 +0200 Subject: [PATCH 02/22] add ComplaintNotification --- app/Notifications/ComplaintNotification.php | 74 +++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 app/Notifications/ComplaintNotification.php diff --git a/app/Notifications/ComplaintNotification.php b/app/Notifications/ComplaintNotification.php new file mode 100644 index 000000000..8ce390f32 --- /dev/null +++ b/app/Notifications/ComplaintNotification.php @@ -0,0 +1,74 @@ +textUrls = $textUrls; + $this->textReason = $textReason; + $this->name = $name; + $this->mailAddress = $mailAddress; + } + + /** + * Get the notification's channels. + * + * @param mixed $notifiable + * @return array|string + */ + public function via($notifiable) + { + return ['mail']; + } + + /** + * Build the mail representation of the notification. + * + * @param mixed $notifiable + * @return \Illuminate\Notifications\Messages\MailMessage + */ + public function toMail($notifiable) + { + $mailAddress = $this->mailAddress ? $this->mailAddress:'None'; + $name = $this->name ? $this->name:'None'; + + $mailFrom = config('app.complaint-mail-sender'); + $mailSubject = config('app.name') . ': Report of Illegal Content'; + + return (new MailMessage) + ->from($mailFrom) + ->subject($mailSubject) + ->line(Lang::get('A message via the wikibase.cloud form for reporting illegal content has been submitted.')) + ->line(Lang::get('Reporter name: ') . $name) + ->line(Lang::get('Reporter email address: ') . $mailAddress) + ->line(Lang::get('Reason:')) + ->line($this->textReason) + ->line('---') + ->line(Lang::get('Reported URLs:')) + ->line($this->textUrls) + ->line('---'); + } +} From 19ca3e90f6641fa8d4d8e3c23c23403cd58fb432 Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 27 Jun 2025 12:45:08 +0200 Subject: [PATCH 03/22] clearer naming --- app/Notifications/ComplaintNotification.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/Notifications/ComplaintNotification.php b/app/Notifications/ComplaintNotification.php index 8ce390f32..39f2be2f2 100644 --- a/app/Notifications/ComplaintNotification.php +++ b/app/Notifications/ComplaintNotification.php @@ -11,24 +11,24 @@ */ class ComplaintNotification extends Notification { - public $textUrls; - public $textReason; + public $offendingUrls; + public $reason; public $name; public $mailAddress; /** * Create a notification instance. * - * @param string $textUrls - * @param string $textReason + * @param string $offendingUrls + * @param string $reason * @param string $name * @param string $mailAddress * @return void */ - public function __construct($textUrls, $textReason, $name='', $mailAddress='') + public function __construct($offendingUrls, $reason, $name='', $mailAddress='') { - $this->textUrls = $textUrls; - $this->textReason = $textReason; + $this->offendingUrls = $offendingUrls; + $this->reason = $reason; $this->name = $name; $this->mailAddress = $mailAddress; } @@ -65,10 +65,10 @@ public function toMail($notifiable) ->line(Lang::get('Reporter name: ') . $name) ->line(Lang::get('Reporter email address: ') . $mailAddress) ->line(Lang::get('Reason:')) - ->line($this->textReason) + ->line($this->reason) ->line('---') ->line(Lang::get('Reported URLs:')) - ->line($this->textUrls) + ->line($this->offendingUrls) ->line('---'); } } From 00dd3ac3dd599e47a9079860cd0b518befadc673 Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 27 Jun 2025 12:45:17 +0200 Subject: [PATCH 04/22] add ComplaintController --- app/Http/Controllers/ComplaintController.php | 89 ++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 app/Http/Controllers/ComplaintController.php diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php new file mode 100644 index 000000000..15968c672 --- /dev/null +++ b/app/Http/Controllers/ComplaintController.php @@ -0,0 +1,89 @@ +recaptchaValidation = $recaptchaValidation; + } + + /** + * Handle a complaint report page request for the application. + * + * @param \Illuminate\Http\Request $request + */ + public function sendMessage(Request $request): \Illuminate\Http\JsonResponse + { + $validator = $this->validator($request->all()); + + if ($validator->fails()) { + $failed = $validator->failed(); + + if (isset($failed['recaptcha'])) { + abort(401); + } else { + abort(400); + } + } + + $validated = $validator->safe(); + + Notification::route('mail', [ + config('app.complaint-mail-recipient'), + ])->notify( + new ComplaintNotification( + $validated['offendingUrls'], + $validated['reason'], + $validated['name'], + $validated['mailAddress'], + ) + ); + + return response()->json('Success', 200); + } + + /** + * Get a validator for an incoming complaint report page request. + */ + protected function validator(array $data): \Illuminate\Validation\Validator + { + if (! isset($data['name'])) { + $data['name'] = ''; + } + + if (! isset($data['mailAddress'])) { + $data['mailAddress'] = ''; + } + + $validation = [ + 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], + 'name' => ['nullable', 'string', 'max:300'], + 'reason' => ['required', 'string', 'max:10000'], + 'offendingUrls' => ['required', 'string', 'max:10000'], + + 'mailAddress' => [ + 'nullable', + 'max:300', + Rule::when( + !empty($mailAddress), + ['email:rfc,dns'] + ), + ], + ]; + + return Validator::make($data, $validation); + } +} From 2a6db8fede1116131943cc5c8f8eaca6d5da60b1 Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 27 Jun 2025 12:46:54 +0200 Subject: [PATCH 05/22] add route --- routes/api.php | 1 + 1 file changed, 1 insertion(+) diff --git a/routes/api.php b/routes/api.php index 015ffd585..9c7aa117e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -18,6 +18,7 @@ $router->post('user/forgotPassword', ['uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail']); $router->post('user/resetPassword', ['uses' => 'Auth\ResetPasswordController@reset']); $router->post('contact/sendMessage', ['uses' => 'ContactController@sendMessage']); + $router->post('complaint/sendMessage', ['uses' => 'ComplaintController@sendMessage']); $router->post('auth/login', ['uses' => 'Auth\LoginController@postLogin'])->name('login'); // Authed From 04461b532c841c7aec9c145ed3cf19536d3bd086 Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 27 Jun 2025 13:00:01 +0200 Subject: [PATCH 06/22] add ExternalComplaintNotification --- app/Http/Controllers/ComplaintController.php | 14 +++++++ app/Notifications/ComplaintNotification.php | 13 +++---- .../ExternalComplaintNotification.php | 38 +++++++++++++++++++ 3 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 app/Notifications/ExternalComplaintNotification.php diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 15968c672..5a14fb3d6 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Notifications\ExternalComplaintNotification; use App\Notifications\ComplaintNotification; use App\Rules\ReCaptchaValidation; use Illuminate\Http\Request; @@ -52,6 +53,19 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse ) ); + if (! empty($validated['mailAddress'])) { + Notification::route('mail', [ + $validated['mailAddress'], + ])->notify( + new ExternalComplaintNotification( + $validated['offendingUrls'], + $validated['reason'], + $validated['name'], + $validated['mailAddress'], + ) + ); + } + return response()->json('Success', 200); } diff --git a/app/Notifications/ComplaintNotification.php b/app/Notifications/ComplaintNotification.php index 39f2be2f2..655975edb 100644 --- a/app/Notifications/ComplaintNotification.php +++ b/app/Notifications/ComplaintNotification.php @@ -25,7 +25,7 @@ class ComplaintNotification extends Notification * @param string $mailAddress * @return void */ - public function __construct($offendingUrls, $reason, $name='', $mailAddress='') + public function __construct($offendingUrls, $reason, $name='None', $mailAddress='None') { $this->offendingUrls = $offendingUrls; $this->reason = $reason; @@ -52,9 +52,6 @@ public function via($notifiable) */ public function toMail($notifiable) { - $mailAddress = $this->mailAddress ? $this->mailAddress:'None'; - $name = $this->name ? $this->name:'None'; - $mailFrom = config('app.complaint-mail-sender'); $mailSubject = config('app.name') . ': Report of Illegal Content'; @@ -62,12 +59,12 @@ public function toMail($notifiable) ->from($mailFrom) ->subject($mailSubject) ->line(Lang::get('A message via the wikibase.cloud form for reporting illegal content has been submitted.')) - ->line(Lang::get('Reporter name: ') . $name) - ->line(Lang::get('Reporter email address: ') . $mailAddress) - ->line(Lang::get('Reason:')) + ->line(Lang::get('Reporter name: ') . $this->name) + ->line(Lang::get('Reporter email address: ') . $this->mailAddress) + ->line(Lang::get('Reason why the information in question is illegal content:')) ->line($this->reason) ->line('---') - ->line(Lang::get('Reported URLs:')) + ->line(Lang::get('URL(s) for the content in question:')) ->line($this->offendingUrls) ->line('---'); } diff --git a/app/Notifications/ExternalComplaintNotification.php b/app/Notifications/ExternalComplaintNotification.php new file mode 100644 index 000000000..b2d538e8f --- /dev/null +++ b/app/Notifications/ExternalComplaintNotification.php @@ -0,0 +1,38 @@ +from($mailFrom) + ->subject($mailSubject) + ->line(Lang::get('Your message via the wikibase.cloud form for reporting illegal content has been submitted.')) + ->line(Lang::get('Name: ') . $this->name) + ->line(Lang::get('Email address: ') . $this->mailAddress) + ->line(Lang::get('Reason why the information in question is illegal content:')) + ->line($this->reason) + ->line('---') + ->line(Lang::get('URL(s) for the content in question:')) + ->line($this->offendingUrls) + ->line('---'); + } +} From 792f422254fe90958304118ef5f16168c8290c7a Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 27 Jun 2025 13:41:43 +0200 Subject: [PATCH 07/22] templating --- app/Http/Controllers/ComplaintController.php | 9 ++------- app/Notifications/ComplaintNotification.php | 18 ++++++++++++++---- .../ExternalComplaintNotification.php | 9 +++++++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 5a14fb3d6..1c8396a37 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -74,13 +74,8 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse */ protected function validator(array $data): \Illuminate\Validation\Validator { - if (! isset($data['name'])) { - $data['name'] = ''; - } - - if (! isset($data['mailAddress'])) { - $data['mailAddress'] = ''; - } + $data['name'] = $data['name'] ?? ''; + $data['mailAddress'] = $data['mailAddress'] ?? ''; $validation = [ 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], diff --git a/app/Notifications/ComplaintNotification.php b/app/Notifications/ComplaintNotification.php index 655975edb..e5b805fb3 100644 --- a/app/Notifications/ComplaintNotification.php +++ b/app/Notifications/ComplaintNotification.php @@ -25,7 +25,7 @@ class ComplaintNotification extends Notification * @param string $mailAddress * @return void */ - public function __construct($offendingUrls, $reason, $name='None', $mailAddress='None') + public function __construct($offendingUrls, $reason, $name=null, $mailAddress=null) { $this->offendingUrls = $offendingUrls; $this->reason = $reason; @@ -52,6 +52,17 @@ public function via($notifiable) */ public function toMail($notifiable) { + $name = $this->name; + $mailAddress = $this->mailAddress; + + if (empty($name)) { + $name = 'None'; + } + + if (empty($mailAddress)) { + $mailAddress = 'None'; + } + $mailFrom = config('app.complaint-mail-sender'); $mailSubject = config('app.name') . ': Report of Illegal Content'; @@ -59,11 +70,10 @@ public function toMail($notifiable) ->from($mailFrom) ->subject($mailSubject) ->line(Lang::get('A message via the wikibase.cloud form for reporting illegal content has been submitted.')) - ->line(Lang::get('Reporter name: ') . $this->name) - ->line(Lang::get('Reporter email address: ') . $this->mailAddress) + ->line(Lang::get('Reporter name: ') . $name) + ->line(Lang::get('Reporter email address: ') . $mailAddress) ->line(Lang::get('Reason why the information in question is illegal content:')) ->line($this->reason) - ->line('---') ->line(Lang::get('URL(s) for the content in question:')) ->line($this->offendingUrls) ->line('---'); diff --git a/app/Notifications/ExternalComplaintNotification.php b/app/Notifications/ExternalComplaintNotification.php index b2d538e8f..09301ec74 100644 --- a/app/Notifications/ExternalComplaintNotification.php +++ b/app/Notifications/ExternalComplaintNotification.php @@ -19,6 +19,12 @@ class ExternalComplaintNotification extends ComplaintNotification */ public function toMail($notifiable) { + $name = $this->name; + + if (empty($name)) { + $name = 'None'; + } + $mailFrom = config('app.complaint-mail-sender'); $mailSubject = config('app.name') . ': Report of Illegal Content'; @@ -26,11 +32,10 @@ public function toMail($notifiable) ->from($mailFrom) ->subject($mailSubject) ->line(Lang::get('Your message via the wikibase.cloud form for reporting illegal content has been submitted.')) - ->line(Lang::get('Name: ') . $this->name) + ->line(Lang::get('Name: ') . $name) ->line(Lang::get('Email address: ') . $this->mailAddress) ->line(Lang::get('Reason why the information in question is illegal content:')) ->line($this->reason) - ->line('---') ->line(Lang::get('URL(s) for the content in question:')) ->line($this->offendingUrls) ->line('---'); From 7cf1963258854a0097c86c35d1bc6bbef9242e46 Mon Sep 17 00:00:00 2001 From: dena Date: Mon, 30 Jun 2025 15:49:54 +0200 Subject: [PATCH 08/22] switch order of notifications --- app/Http/Controllers/ComplaintController.php | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 1c8396a37..e555e78f4 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -42,17 +42,6 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse $validated = $validator->safe(); - Notification::route('mail', [ - config('app.complaint-mail-recipient'), - ])->notify( - new ComplaintNotification( - $validated['offendingUrls'], - $validated['reason'], - $validated['name'], - $validated['mailAddress'], - ) - ); - if (! empty($validated['mailAddress'])) { Notification::route('mail', [ $validated['mailAddress'], @@ -66,6 +55,17 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse ); } + Notification::route('mail', [ + config('app.complaint-mail-recipient'), + ])->notify( + new ComplaintNotification( + $validated['offendingUrls'], + $validated['reason'], + $validated['name'], + $validated['mailAddress'], + ) + ); + return response()->json('Success', 200); } From fd16dcae1e8169c9897ed2d73c63abc688b422fc Mon Sep 17 00:00:00 2001 From: dena Date: Mon, 7 Jul 2025 11:52:47 +0200 Subject: [PATCH 09/22] add WIP tests --- tests/Routes/Complaint/SendMessageTest.php | 134 +++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 tests/Routes/Complaint/SendMessageTest.php diff --git a/tests/Routes/Complaint/SendMessageTest.php b/tests/Routes/Complaint/SendMessageTest.php new file mode 100644 index 000000000..d1a5e6aeb --- /dev/null +++ b/tests/Routes/Complaint/SendMessageTest.php @@ -0,0 +1,134 @@ + '', + 'mailAddress' => '', + 'reason' => '', + 'offendingUrls' => '', + 'recaptcha' => '', + ]; + + protected $postDataTemplateFilled = [ + 'name' => 'Jane Doe', + 'mailAddress' => 'jane.doe@example.com', + 'reason' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', + 'offendingUrls' => 'https://example.com/1, https://example.com/2, https://example.com/3', + 'recaptcha' => 'fake-token', + ]; + + private function mockReCaptchaValidation($passes=true) + { + // replace injected ReCaptchaValidation class with mock (ComplaintController::$recaptchaValidation) + $mockRule = $this->createMock(ReCaptchaValidation::class); + $mockRule->method('passes') + ->willReturn($passes); + + $this->app->instance(ReCaptchaValidation::class, $mockRule); + } + + public function testSendMessage_NoData() + { + $this->mockReCaptchaValidation(false); + + $data = $this->postDataTemplateEmpty; + + $response = $this->json('POST', $this->route, $data); + $response->assertStatus(401); + } + + public function testSendMessage_InvalidMailAddress() + { + $this->mockReCaptchaValidation(); + + $data = $this->postDataTemplateFilled; + $data['mailAddress'] = "invalid-mail-address"; + $response = $this->json('POST', $this->route, $data); + $response->assertStatus(400); + } + + public function testSendMessage_ReasonTooLong() + { + $this->mockReCaptchaValidation(); + + $data = $this->postDataTemplateFilled; + $data['reason'] = str_repeat("Hi!", 10000); + $response = $this->json('POST', $this->route, $data); + $response->assertStatus(400); + } + + public function testSendMessage_NameTooLong() + { + $this->mockReCaptchaValidation(); + + $data = $this->postDataTemplateFilled; + $data['name'] = str_repeat("Hi!", 10000); + $response = $this->json('POST', $this->route, $data); + $response->assertStatus(400); + } + + public function testSendMessage_OffendingUrlsTooLong() + { + $this->mockReCaptchaValidation(); + + $data = $this->postDataTemplateFilled; + $data['offendingUrls'] = str_repeat("Hi!", 10000); + $response = $this->json('POST', $this->route, $data); + $response->assertStatus(400); + } + + + public function testSendMessage_NoNameNorMailAddress() + { + $this->mockReCaptchaValidation(); + Notification::fake(); + + $data = $this->postDataTemplateFilled; + $data['name'] = ''; + $data['mailAddress'] = ''; + + $response = $this->json('POST', $this->route, $data); + $response->assertStatus(200); + } + + public function testSendMessage_Success() + { + $this->mockReCaptchaValidation(); + Notification::fake(); + + $data = $this->postDataTemplateFilled; + + $response = $this->json('POST', $this->route, $data); + $response->assertStatus(200); + Notification::assertSentTo(new AnonymousNotifiable(), ComplaintNotification::class, function ($notification) { + $this->assertSame( + "dsa@wikibase.cloud", + $notification->toMail(new AnonymousNotifiable())->from[0] + ); + return true; + }); + } + + public function testSendMessage_RecaptchaFailure() + { + $this->mockReCaptchaValidation(false); + Notification::fake(); + + $response = $this->json('POST', $this->route, $this->postDataTemplateFilled); + $response->assertStatus(401); + + Notification::assertNothingSent(); + } +} From dec3ba993551a288b1984d27a11f9b9540aae870 Mon Sep 17 00:00:00 2001 From: dena Date: Mon, 7 Jul 2025 12:04:32 +0200 Subject: [PATCH 10/22] restrict email validation to rfc filter --- app/Http/Controllers/ComplaintController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index e555e78f4..19323e28e 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -88,7 +88,7 @@ protected function validator(array $data): \Illuminate\Validation\Validator 'max:300', Rule::when( !empty($mailAddress), - ['email:rfc,dns'] + ['email:rfc'] ), ], ]; From 070353fb512728801645c5d48cf2b383ffca7b76 Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 10 Jul 2025 16:52:03 +0200 Subject: [PATCH 11/22] fix email validation rule condition --- app/Http/Controllers/ComplaintController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 19323e28e..61e418abf 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -87,7 +87,7 @@ protected function validator(array $data): \Illuminate\Validation\Validator 'nullable', 'max:300', Rule::when( - !empty($mailAddress), + !empty($data['mailAddress']), ['email:rfc'] ), ], From 685d5e8c010e55c2a9a4c91bd86d44d694d0fde7 Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 10 Jul 2025 16:58:07 +0200 Subject: [PATCH 12/22] add multi mail address test case --- tests/Routes/Complaint/SendMessageTest.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/Routes/Complaint/SendMessageTest.php b/tests/Routes/Complaint/SendMessageTest.php index d1a5e6aeb..76eb7ec4a 100644 --- a/tests/Routes/Complaint/SendMessageTest.php +++ b/tests/Routes/Complaint/SendMessageTest.php @@ -49,7 +49,7 @@ public function testSendMessage_NoData() $response->assertStatus(401); } - public function testSendMessage_InvalidMailAddress() + public function testSendMessage_InvalidMailAddressRfc() { $this->mockReCaptchaValidation(); @@ -59,6 +59,16 @@ public function testSendMessage_InvalidMailAddress() $response->assertStatus(400); } + public function testSendMessage_InvalidMailAddressMulti() + { + $this->mockReCaptchaValidation(); + + $data = $this->postDataTemplateFilled; + $data['mailAddress'] = "mail@example.com, foo@bar.com"; + $response = $this->json('POST', $this->route, $data); + $response->assertStatus(400); + } + public function testSendMessage_ReasonTooLong() { $this->mockReCaptchaValidation(); @@ -89,7 +99,6 @@ public function testSendMessage_OffendingUrlsTooLong() $response->assertStatus(400); } - public function testSendMessage_NoNameNorMailAddress() { $this->mockReCaptchaValidation(); From 490e2772df875dff6c24ab1fb87a09567a99d41c Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 11 Jul 2025 10:53:04 +0200 Subject: [PATCH 13/22] refactored class naming --- app/Http/Controllers/ComplaintController.php | 4 ++-- app/Notifications/ComplaintNotification.php | 2 +- ...aintNotification.php => ComplaintNotificationExternal.php} | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename app/Notifications/{ExternalComplaintNotification.php => ComplaintNotificationExternal.php} (95%) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 61e418abf..2ad9bca16 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers; -use App\Notifications\ExternalComplaintNotification; +use App\Notifications\ComplaintNotificationExternal; use App\Notifications\ComplaintNotification; use App\Rules\ReCaptchaValidation; use Illuminate\Http\Request; @@ -46,7 +46,7 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse Notification::route('mail', [ $validated['mailAddress'], ])->notify( - new ExternalComplaintNotification( + new ComplaintNotificationExternal( $validated['offendingUrls'], $validated['reason'], $validated['name'], diff --git a/app/Notifications/ComplaintNotification.php b/app/Notifications/ComplaintNotification.php index e5b805fb3..85c98de93 100644 --- a/app/Notifications/ComplaintNotification.php +++ b/app/Notifications/ComplaintNotification.php @@ -41,7 +41,7 @@ public function __construct($offendingUrls, $reason, $name=null, $mailAddress=nu */ public function via($notifiable) { - return ['mail']; + return ['database', 'mail']; } /** diff --git a/app/Notifications/ExternalComplaintNotification.php b/app/Notifications/ComplaintNotificationExternal.php similarity index 95% rename from app/Notifications/ExternalComplaintNotification.php rename to app/Notifications/ComplaintNotificationExternal.php index 09301ec74..9d0740282 100644 --- a/app/Notifications/ExternalComplaintNotification.php +++ b/app/Notifications/ComplaintNotificationExternal.php @@ -9,7 +9,7 @@ /** * A notification to be sent when the legal complaint form is being used. */ -class ExternalComplaintNotification extends ComplaintNotification +class ComplaintNotificationExternal extends ComplaintNotification { /** * Build the mail representation of the notification. From 5dce2b43ec88b23a7a0745e1de2ba54f70e365fa Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 11 Jul 2025 11:27:12 +0200 Subject: [PATCH 14/22] WIP persist notifications in database --- app/Http/Controllers/ComplaintController.php | 12 +++++++----- app/Notifications/ComplaintNotification.php | 7 +++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 2ad9bca16..8e6cb2973 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -43,16 +43,18 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse $validated = $validator->safe(); if (! empty($validated['mailAddress'])) { - Notification::route('mail', [ - $validated['mailAddress'], - ])->notify( - new ComplaintNotificationExternal( + $internalNotification = new ComplaintNotificationExternal( $validated['offendingUrls'], $validated['reason'], $validated['name'], $validated['mailAddress'], - ) ); + + Notification::route('mail', [ + $validated['mailAddress'], + ])->notify($internalNotification); + + Notification::route('database', $validated['mailAddress'])->notify($internalNotification); } Notification::route('mail', [ diff --git a/app/Notifications/ComplaintNotification.php b/app/Notifications/ComplaintNotification.php index 85c98de93..98ff38141 100644 --- a/app/Notifications/ComplaintNotification.php +++ b/app/Notifications/ComplaintNotification.php @@ -2,6 +2,7 @@ namespace App\Notifications; +use Illuminate\Notifications\Messages\DatabaseMessage; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; use Illuminate\Support\Facades\Lang; @@ -78,4 +79,10 @@ public function toMail($notifiable) ->line($this->offendingUrls) ->line('---'); } + + public function toDatabase($notifiable) { + $mail = $this->toMail($notifiable); + + return (new DatabaseMessage($mail->toArray())); + } } From d76b9d5fbd5df2b19c5c25e4216e48fa9bc0f940 Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 18 Jul 2025 13:27:15 +0200 Subject: [PATCH 15/22] add ComplaintRecord class --- app/ComplaintRecord.php | 37 ++++++++++++++++++ app/Http/Controllers/ComplaintController.php | 39 ++++++++++++------- database/factories/ComplaintRecordFactory.php | 33 ++++++++++++++++ ..._103841_create_complaint_records_table.php | 32 +++++++++++++++ 4 files changed, 126 insertions(+), 15 deletions(-) create mode 100644 app/ComplaintRecord.php create mode 100644 database/factories/ComplaintRecordFactory.php create mode 100644 database/migrations/2025_07_18_103841_create_complaint_records_table.php diff --git a/app/ComplaintRecord.php b/app/ComplaintRecord.php new file mode 100644 index 000000000..7dc435ab2 --- /dev/null +++ b/app/ComplaintRecord.php @@ -0,0 +1,37 @@ +dispatched_at = Carbon::now(); + } +} diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 8e6cb2973..ec2a989e1 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -9,6 +9,7 @@ use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Notification; use Illuminate\Validation\Rule; +use App\ComplaintRecord; class ComplaintController extends Controller { @@ -42,32 +43,40 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse $validated = $validator->safe(); - if (! empty($validated['mailAddress'])) { - $internalNotification = new ComplaintNotificationExternal( - $validated['offendingUrls'], - $validated['reason'], - $validated['name'], - $validated['mailAddress'], - ); + $complaintRecord = new ComplaintRecord; + $complaintRecord->name = $validated['name']; + $complaintRecord->mail_address = $validated['mailAddress']; + $complaintRecord->reason = $validated['reason']; + $complaintRecord->offending_urls = $validated['offendingUrls']; + $complaintRecord->save(); + if (! empty($validated['mailAddress'])) { Notification::route('mail', [ $validated['mailAddress'], - ])->notify($internalNotification); - - Notification::route('database', $validated['mailAddress'])->notify($internalNotification); + ])->notify( + new ComplaintNotificationExternal( + $complaintRecord->offending_urls, + $complaintRecord->reason, + $complaintRecord->name, + $complaintRecord->mail_address, + ) + ); } Notification::route('mail', [ config('app.complaint-mail-recipient'), ])->notify( - new ComplaintNotification( - $validated['offendingUrls'], - $validated['reason'], - $validated['name'], - $validated['mailAddress'], + new ComplaintNotification( + $complaintRecord->offending_urls, + $complaintRecord->reason, + $complaintRecord->name, + $complaintRecord->mail_address, ) ); + $complaintRecord->markAsDispatched(); + $complaintRecord->save(); + return response()->json('Success', 200); } diff --git a/database/factories/ComplaintRecordFactory.php b/database/factories/ComplaintRecordFactory.php new file mode 100644 index 000000000..90d8de135 --- /dev/null +++ b/database/factories/ComplaintRecordFactory.php @@ -0,0 +1,33 @@ + + */ +class ComplaintRecordFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var class-string + */ + protected $model = ComplaintRecord::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'dispatched' => null, + ]; + } +} diff --git a/database/migrations/2025_07_18_103841_create_complaint_records_table.php b/database/migrations/2025_07_18_103841_create_complaint_records_table.php new file mode 100644 index 000000000..44f4f8219 --- /dev/null +++ b/database/migrations/2025_07_18_103841_create_complaint_records_table.php @@ -0,0 +1,32 @@ +id(); + $table->timestamps(); + $table->timestamp('dispatched_at')->nullable(); + $table->string('name')->nullable(); + $table->string('mail_address')->nullable(); + $table->text('reason'); + $table->text('offending_urls'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('complaint_records'); + } +}; From ff9704d157f86cc957c50ce8430b4b9916d15fb3 Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 18 Jul 2025 13:57:57 +0200 Subject: [PATCH 16/22] extend test cases --- tests/Routes/Complaint/SendMessageTest.php | 89 +++++++++++++++++++++- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/tests/Routes/Complaint/SendMessageTest.php b/tests/Routes/Complaint/SendMessageTest.php index 76eb7ec4a..1b57661f3 100644 --- a/tests/Routes/Complaint/SendMessageTest.php +++ b/tests/Routes/Complaint/SendMessageTest.php @@ -2,15 +2,19 @@ namespace Tests\Routes\Complaint; +use App\ComplaintRecord; use App\Notifications\ComplaintNotification; use App\Rules\ReCaptchaValidation; use Illuminate\Notifications\AnonymousNotifiable; use Illuminate\Support\Facades\Notification; use Tests\TestCase; use Tests\Feature\ReCaptchaValidationTest; +use Illuminate\Foundation\Testing\RefreshDatabase; class SendMessageTest extends TestCase { + use RefreshDatabase; + protected $route = 'complaint/sendMessage'; protected $postDataTemplateEmpty = [ @@ -38,71 +42,141 @@ private function mockReCaptchaValidation($passes=true) $this->app->instance(ReCaptchaValidation::class, $mockRule); } + private function assertRecordCount(int $count) + { + $this->assertEquals(ComplaintRecord::count(), $count); + } + + private function assertComplaintMarkedAsDispatched() + { + $complaintRecord = ComplaintRecord::first(); + $this->assertNotEmpty($complaintRecord->dispatched_at); + } + + private function assertComplaintNotMarkedAsDispatched() + { + $complaintRecord = ComplaintRecord::first(); + $this->assertEmpty($complaintRecord->dispatched_at); + } + + private function assertComplaintRecorded() + { + $this->assertRecordCount(1); + } + + private function assertComplaintNotRecorded() + { + $this->assertRecordCount(0); + } + + public function testRecordOnMailFail() + { + $this->mockReCaptchaValidation(); + + $data = $this->postDataTemplateFilled; + + try { + $response = $this->json('POST', $this->route, $data); + } catch(\Symfony\Component\Mailer\Exception\TransportException $e) { + return; + } + + $response->assertStatus(500); + + $this->assertComplaintRecorded(); + $this->assertComplaintNotMarkedAsDispatched(); + } public function testSendMessage_NoData() { + Notification::fake(); $this->mockReCaptchaValidation(false); $data = $this->postDataTemplateEmpty; $response = $this->json('POST', $this->route, $data); $response->assertStatus(401); + + Notification::assertNothingSent(); + $this->assertComplaintNotRecorded(); } public function testSendMessage_InvalidMailAddressRfc() { + Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; $data['mailAddress'] = "invalid-mail-address"; $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); + + $this->assertEquals(ComplaintRecord::count(), 0); + + Notification::assertNothingSent(); + $this->assertComplaintNotRecorded(); } public function testSendMessage_InvalidMailAddressMulti() { + Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; $data['mailAddress'] = "mail@example.com, foo@bar.com"; $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); + + Notification::assertNothingSent(); + $this->assertComplaintNotRecorded(); } public function testSendMessage_ReasonTooLong() { + Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; $data['reason'] = str_repeat("Hi!", 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); + + Notification::assertNothingSent(); + $this->assertComplaintNotRecorded(); } public function testSendMessage_NameTooLong() { + Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; $data['name'] = str_repeat("Hi!", 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); + + Notification::assertNothingSent(); + $this->assertComplaintNotRecorded(); } public function testSendMessage_OffendingUrlsTooLong() { + Notification::fake(); $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; $data['offendingUrls'] = str_repeat("Hi!", 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); + + Notification::assertNothingSent(); + $this->assertComplaintNotRecorded(); } public function testSendMessage_NoNameNorMailAddress() { - $this->mockReCaptchaValidation(); Notification::fake(); + $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; $data['name'] = ''; @@ -110,12 +184,16 @@ public function testSendMessage_NoNameNorMailAddress() $response = $this->json('POST', $this->route, $data); $response->assertStatus(200); + + Notification::assertCount(1); + $this->assertComplaintRecorded(); + $this->assertComplaintMarkedAsDispatched(); } public function testSendMessage_Success() { - $this->mockReCaptchaValidation(); Notification::fake(); + $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; @@ -128,16 +206,21 @@ public function testSendMessage_Success() ); return true; }); + + Notification::assertCount(2); + $this->assertComplaintRecorded(); + $this->assertComplaintMarkedAsDispatched(); } public function testSendMessage_RecaptchaFailure() { - $this->mockReCaptchaValidation(false); Notification::fake(); + $this->mockReCaptchaValidation(false); $response = $this->json('POST', $this->route, $this->postDataTemplateFilled); $response->assertStatus(401); Notification::assertNothingSent(); + $this->assertComplaintNotRecorded(); } } From 41e924ff69a75e8d49bd2b1eb122020fa0a22882 Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 18 Jul 2025 14:20:44 +0200 Subject: [PATCH 17/22] adjust field names to UI code --- app/Http/Controllers/ComplaintController.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index ec2a989e1..ee2a4d08e 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -45,14 +45,14 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse $complaintRecord = new ComplaintRecord; $complaintRecord->name = $validated['name']; - $complaintRecord->mail_address = $validated['mailAddress']; - $complaintRecord->reason = $validated['reason']; - $complaintRecord->offending_urls = $validated['offendingUrls']; + $complaintRecord->mail_address = $validated['email']; + $complaintRecord->reason = $validated['message']; + $complaintRecord->offending_urls = $validated['url']; $complaintRecord->save(); - if (! empty($validated['mailAddress'])) { + if (! empty($complaintRecord->mail_address)) { Notification::route('mail', [ - $validated['mailAddress'], + $complaintRecord->mail_address, ])->notify( new ComplaintNotificationExternal( $complaintRecord->offending_urls, @@ -86,15 +86,15 @@ public function sendMessage(Request $request): \Illuminate\Http\JsonResponse protected function validator(array $data): \Illuminate\Validation\Validator { $data['name'] = $data['name'] ?? ''; - $data['mailAddress'] = $data['mailAddress'] ?? ''; + $data['email'] = $data['email'] ?? ''; $validation = [ 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], 'name' => ['nullable', 'string', 'max:300'], - 'reason' => ['required', 'string', 'max:10000'], - 'offendingUrls' => ['required', 'string', 'max:10000'], + 'message' => ['required', 'string', 'max:10000'], + 'url' => ['required', 'string', 'max:10000'], - 'mailAddress' => [ + 'email' => [ 'nullable', 'max:300', Rule::when( From 73ba6e9519404f2bbba2a65cf22613d1ccb5f2bc Mon Sep 17 00:00:00 2001 From: dena Date: Fri, 18 Jul 2025 15:55:32 +0200 Subject: [PATCH 18/22] fix testRecordOnMailFail status code assert --- tests/Routes/Complaint/SendMessageTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Routes/Complaint/SendMessageTest.php b/tests/Routes/Complaint/SendMessageTest.php index 1b57661f3..e9564d77e 100644 --- a/tests/Routes/Complaint/SendMessageTest.php +++ b/tests/Routes/Complaint/SendMessageTest.php @@ -81,7 +81,7 @@ public function testRecordOnMailFail() return; } - $response->assertStatus(500); + $this->assertNotEquals($response->status(), 200); $this->assertComplaintRecorded(); $this->assertComplaintNotMarkedAsDispatched(); From 07af1b7531649bb9594820aa3070e963c735858e Mon Sep 17 00:00:00 2001 From: dena Date: Mon, 21 Jul 2025 13:21:32 +0200 Subject: [PATCH 19/22] adjust parameter names in test case --- tests/Routes/Complaint/SendMessageTest.php | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/Routes/Complaint/SendMessageTest.php b/tests/Routes/Complaint/SendMessageTest.php index e9564d77e..668517ebc 100644 --- a/tests/Routes/Complaint/SendMessageTest.php +++ b/tests/Routes/Complaint/SendMessageTest.php @@ -18,19 +18,19 @@ class SendMessageTest extends TestCase protected $route = 'complaint/sendMessage'; protected $postDataTemplateEmpty = [ - 'name' => '', - 'mailAddress' => '', - 'reason' => '', - 'offendingUrls' => '', - 'recaptcha' => '', + 'name' => '', + 'email' => '', + 'message' => '', + 'url' => '', + 'recaptcha' => '', ]; protected $postDataTemplateFilled = [ - 'name' => 'Jane Doe', - 'mailAddress' => 'jane.doe@example.com', - 'reason' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', - 'offendingUrls' => 'https://example.com/1, https://example.com/2, https://example.com/3', - 'recaptcha' => 'fake-token', + 'name' => 'Jane Doe', + 'email' => 'jane.doe@example.com', + 'message' => 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.', + 'url' => 'https://example.com/1, https://example.com/2, https://example.com/3', + 'recaptcha' => 'fake-token', ]; private function mockReCaptchaValidation($passes=true) @@ -107,7 +107,7 @@ public function testSendMessage_InvalidMailAddressRfc() $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['mailAddress'] = "invalid-mail-address"; + $data['email'] = "invalid-mail-address"; $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); @@ -123,7 +123,7 @@ public function testSendMessage_InvalidMailAddressMulti() $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['mailAddress'] = "mail@example.com, foo@bar.com"; + $data['email'] = "mail@example.com, foo@bar.com"; $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); @@ -165,7 +165,7 @@ public function testSendMessage_OffendingUrlsTooLong() $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['offendingUrls'] = str_repeat("Hi!", 10000); + $data['url'] = str_repeat("Hi!", 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); @@ -180,7 +180,7 @@ public function testSendMessage_NoNameNorMailAddress() $data = $this->postDataTemplateFilled; $data['name'] = ''; - $data['mailAddress'] = ''; + $data['email'] = ''; $response = $this->json('POST', $this->route, $data); $response->assertStatus(200); From f6e6436f267c2624bf0883117d16cd8a2d8646ff Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 22 Jul 2025 12:05:46 +0200 Subject: [PATCH 20/22] reduce size limit of text fields to 1000 --- app/Http/Controllers/ComplaintController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index ee2a4d08e..0cee6012c 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -91,8 +91,8 @@ protected function validator(array $data): \Illuminate\Validation\Validator $validation = [ 'recaptcha' => ['required', 'string', 'bail', $this->recaptchaValidation], 'name' => ['nullable', 'string', 'max:300'], - 'message' => ['required', 'string', 'max:10000'], - 'url' => ['required', 'string', 'max:10000'], + 'message' => ['required', 'string', 'max:1000'], + 'url' => ['required', 'string', 'max:1000'], 'email' => [ 'nullable', From d0917e60ad3206177d18722573ce48176a98a401 Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 22 Jul 2025 12:44:00 +0200 Subject: [PATCH 21/22] fix field names in test --- app/Http/Controllers/ComplaintController.php | 3 ++- tests/Routes/Complaint/SendMessageTest.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/ComplaintController.php b/app/Http/Controllers/ComplaintController.php index 0cee6012c..d59941c15 100644 --- a/app/Http/Controllers/ComplaintController.php +++ b/app/Http/Controllers/ComplaintController.php @@ -10,6 +10,7 @@ use Illuminate\Support\Facades\Notification; use Illuminate\Validation\Rule; use App\ComplaintRecord; +use Illuminate\Support\Facades\Log; class ComplaintController extends Controller { @@ -98,7 +99,7 @@ protected function validator(array $data): \Illuminate\Validation\Validator 'nullable', 'max:300', Rule::when( - !empty($data['mailAddress']), + !empty($data['email']), ['email:rfc'] ), ], diff --git a/tests/Routes/Complaint/SendMessageTest.php b/tests/Routes/Complaint/SendMessageTest.php index 668517ebc..998f66a99 100644 --- a/tests/Routes/Complaint/SendMessageTest.php +++ b/tests/Routes/Complaint/SendMessageTest.php @@ -137,7 +137,7 @@ public function testSendMessage_ReasonTooLong() $this->mockReCaptchaValidation(); $data = $this->postDataTemplateFilled; - $data['reason'] = str_repeat("Hi!", 10000); + $data['message'] = str_repeat("Hi!", 10000); $response = $this->json('POST', $this->route, $data); $response->assertStatus(400); From b24b994659919fc64402a2f84bdc413836e80a27 Mon Sep 17 00:00:00 2001 From: dena Date: Tue, 22 Jul 2025 13:15:54 +0200 Subject: [PATCH 22/22] remove form contents from externail mail notification --- app/Notifications/ComplaintNotificationExternal.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/Notifications/ComplaintNotificationExternal.php b/app/Notifications/ComplaintNotificationExternal.php index 9d0740282..fb01370df 100644 --- a/app/Notifications/ComplaintNotificationExternal.php +++ b/app/Notifications/ComplaintNotificationExternal.php @@ -32,12 +32,6 @@ public function toMail($notifiable) ->from($mailFrom) ->subject($mailSubject) ->line(Lang::get('Your message via the wikibase.cloud form for reporting illegal content has been submitted.')) - ->line(Lang::get('Name: ') . $name) - ->line(Lang::get('Email address: ') . $this->mailAddress) - ->line(Lang::get('Reason why the information in question is illegal content:')) - ->line($this->reason) - ->line(Lang::get('URL(s) for the content in question:')) - ->line($this->offendingUrls) ->line('---'); } }