From 1c980d4e13f090083d0dde2026e153ee5def1de4 Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 9 Jul 2026 17:43:37 +0200 Subject: [PATCH 1/7] starting implementation of policy array acceptance --- .../Controllers/Auth/RegisterController.php | 3 +- app/Jobs/UserCreateJob.php | 31 ++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 566fa518..439f3430 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -35,7 +35,8 @@ public function register(Request $request) { DB::transaction(function () use (&$user, $request): void { $user = (new UserCreateJob( $request->input('email'), - $request->input('password') + $request->input('password'), + $request->input('accepted_policies') ))->handle(); (UserVerificationCreateTokenAndSendJob::newForAccountCreation($user))->handle(); }); diff --git a/app/Jobs/UserCreateJob.php b/app/Jobs/UserCreateJob.php index 958bfc13..2bf5bc4a 100644 --- a/app/Jobs/UserCreateJob.php +++ b/app/Jobs/UserCreateJob.php @@ -12,11 +12,12 @@ class UserCreateJob extends Job { private $verified; - public function __construct($email, $password, $verified = false) { + public function __construct($email, $password, $acceptedPolicyIds, $verified = false) { // TODO maybe pass in an unsaved eloquent model? // // but that would make CLI job creation hard $this->email = $email; $this->password = $password; + $this->acceptedPolicyIds = $acceptedPolicyIds; $this->verified = false; } @@ -30,6 +31,34 @@ public function handle() { 'verified' => $this->verified, ]); + // accept latest Terms of Use Policy automatically + $latestToU = TermsOfUseVersion::latestActiveVersion(); + if ($latestToU) { + UserTermsOfUseAcceptance::create([ + 'user_id' => $user->id, + 'tou_version' => $latestToU->version, + 'tou_accepted_at' => now(), + ]); + } else { + Log::warning("No active Terms of Use version found when creating user {$user->email} (ID {$user->id})."); + } + + if (is_array($this->acceptedPolicies)) { + foreach($acceptedPolicyIds as $acceptedPolicyId) { + $policy = Policy::find($acceptedPolicyId); + + if ($policy) { + PolicyAcceptance::create([ + 'user_id' => $user->id, + 'policy_id' => $policy->id, + 'accepted_at' => now(), + ]); + } else { + Log::warning("Policy ID '{$acceptedPolicyId}' not found when creating user {$user->email} (ID {$user->id})."); + } + } + } + return $user; } From 8d9a9caab26cbf5495e9c9e9fb26d8c51865e6a6 Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 9 Jul 2026 16:09:30 +0200 Subject: [PATCH 2/7] fix var name --- app/Jobs/UserCreateJob.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Jobs/UserCreateJob.php b/app/Jobs/UserCreateJob.php index 2bf5bc4a..60e5d51f 100644 --- a/app/Jobs/UserCreateJob.php +++ b/app/Jobs/UserCreateJob.php @@ -43,7 +43,7 @@ public function handle() { Log::warning("No active Terms of Use version found when creating user {$user->email} (ID {$user->id})."); } - if (is_array($this->acceptedPolicies)) { + if (is_array($this->acceptedPolicyIds)) { foreach($acceptedPolicyIds as $acceptedPolicyId) { $policy = Policy::find($acceptedPolicyId); From 0d154035578afe12c34ff7480f9acb9853d7a048 Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 9 Jul 2026 17:44:13 +0200 Subject: [PATCH 3/7] add new parameter --- tests/Jobs/UserTermsOfUseAcceptanceTest.php | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/Jobs/UserTermsOfUseAcceptanceTest.php diff --git a/tests/Jobs/UserTermsOfUseAcceptanceTest.php b/tests/Jobs/UserTermsOfUseAcceptanceTest.php new file mode 100644 index 00000000..28cde503 --- /dev/null +++ b/tests/Jobs/UserTermsOfUseAcceptanceTest.php @@ -0,0 +1,32 @@ +handle(); + $email = 'test+' . uniqid('', true) . '@example.com'; + $user = (new UserCreateJob($email, 'thisisapassword123', null, true))->handle(); + + $this->assertDatabaseHas('tou_acceptances', [ + 'user_id' => $user->id, + 'tou_version' => TermsOfUseVersion::latestActiveVersion()->version, + ]); + + $rows = UserTermsOfUseAcceptance::where('user_id', $user->id)->get(); + $this->assertCount(1, $rows); + $acceptance = $rows->first(); + + $this->assertSame(TermsOfUseVersion::latestActiveVersion()->version, $acceptance->tou_version); + $this->assertNotNull($acceptance->tou_accepted_at); + } +} From 9893bc016eef8bd3bc89ed2df0721d0cf835705b Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 9 Jul 2026 16:51:54 +0200 Subject: [PATCH 4/7] fix var access --- app/Jobs/UserCreateJob.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Jobs/UserCreateJob.php b/app/Jobs/UserCreateJob.php index 60e5d51f..9beecb05 100644 --- a/app/Jobs/UserCreateJob.php +++ b/app/Jobs/UserCreateJob.php @@ -44,7 +44,7 @@ public function handle() { } if (is_array($this->acceptedPolicyIds)) { - foreach($acceptedPolicyIds as $acceptedPolicyId) { + foreach($this->acceptedPolicyIds as $acceptedPolicyId) { $policy = Policy::find($acceptedPolicyId); if ($policy) { From 8b205cf55b0f9c23fb54ea2f5c28d7d82526547c Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 9 Jul 2026 17:08:23 +0200 Subject: [PATCH 5/7] add class imports --- app/Jobs/UserCreateJob.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/Jobs/UserCreateJob.php b/app/Jobs/UserCreateJob.php index 9beecb05..253b318f 100644 --- a/app/Jobs/UserCreateJob.php +++ b/app/Jobs/UserCreateJob.php @@ -3,6 +3,9 @@ namespace App\Jobs; use App\User; +use App\UserTermsOfUseAcceptance; +use App\Policy; +use App\PolicyAcceptance; use Illuminate\Support\Facades\Hash; class UserCreateJob extends Job { From 2fcfbfef307c108b7ba74a6587526a18bdd948f7 Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 9 Jul 2026 17:08:38 +0200 Subject: [PATCH 6/7] add tests --- tests/Jobs/UserAcceptedPoliciesTest.php | 70 +++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 tests/Jobs/UserAcceptedPoliciesTest.php diff --git a/tests/Jobs/UserAcceptedPoliciesTest.php b/tests/Jobs/UserAcceptedPoliciesTest.php new file mode 100644 index 00000000..d2421c9b --- /dev/null +++ b/tests/Jobs/UserAcceptedPoliciesTest.php @@ -0,0 +1,70 @@ +handle(); + + $this->assertEquals( + PolicyAcceptance::all()->count(), + 0 + ); + } + + public function testUserRegistrationAcceptsOne(): void { + $termsOfUse = new Policy; + $termsOfUse->policy_type = 'terms-of-use'; + $termsOfUse->active_from = CarbonImmutable::now(); + $termsOfUse->content_vue_file = 'termsOfUse.vue'; + $termsOfUse->save(); + + $email = 'test+' . uniqid('', true) . '@example.com'; + $user = (new UserCreateJob($email, 'thisisapassword123', [$termsOfUse->id], true))->handle(); + + $this->assertDatabaseHas('policy_acceptances', [ + 'user_id' => $user->id, + 'policy_id' => $termsOfUse->id, + ]); + } + + public function testUserRegistrationAcceptsTwo(): void { + $termsOfUse = new Policy; + $termsOfUse->policy_type = 'terms-of-use'; + $termsOfUse->active_from = CarbonImmutable::now(); + $termsOfUse->content_vue_file = 'termsOfUse.vue'; + $termsOfUse->save(); + + $hostingPolicy = new Policy; + $hostingPolicy->policy_type = 'hosting-policy'; + $hostingPolicy->active_from = CarbonImmutable::now(); + $hostingPolicy->content_vue_file = 'hostingPolicy.vue'; + $hostingPolicy->save(); + + $email = 'test+' . uniqid('', true) . '@example.com'; + $user = (new UserCreateJob($email, 'thisisapassword123', [$termsOfUse->id, $hostingPolicy->id], true))->handle(); + + $this->assertDatabaseHas('policy_acceptances', [ + 'user_id' => $user->id, + 'policy_id' => $termsOfUse->id, + ]); + + $this->assertDatabaseHas('policy_acceptances', [ + 'user_id' => $user->id, + 'policy_id' => $hostingPolicy->id, + ]); + } +} From 9e2586b10029414f75267cc904f79047510d3446 Mon Sep 17 00:00:00 2001 From: dena Date: Thu, 9 Jul 2026 18:03:52 +0200 Subject: [PATCH 7/7] add import --- app/Jobs/UserCreateJob.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Jobs/UserCreateJob.php b/app/Jobs/UserCreateJob.php index 253b318f..2b9b20a8 100644 --- a/app/Jobs/UserCreateJob.php +++ b/app/Jobs/UserCreateJob.php @@ -6,6 +6,7 @@ use App\UserTermsOfUseAcceptance; use App\Policy; use App\PolicyAcceptance; +use App\TermsOfUseVersion use Illuminate\Support\Facades\Hash; class UserCreateJob extends Job {