Feat: Recording Legal Acceptance
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Which terms/privacy policy version an account was created under — the
|
||||||
|
* storefront login page shows a notice ("By continuing, you accept the
|
||||||
|
* Terms of Use and have read the Privacy Policy") that a new signup
|
||||||
|
* implicitly agrees to just by requesting an OTP code, so this is
|
||||||
|
* recorded the moment Modules\Core\Auth\Services\UserOtpService::
|
||||||
|
* generateAndSend()'s firstOrCreate() actually creates the row — never
|
||||||
|
* for an existing user, whose original acceptance (whatever version was
|
||||||
|
* live at the time) must not be silently overwritten by a later config
|
||||||
|
* value. Nullable: every user created before this migration has none of
|
||||||
|
* the three, which is the honest answer ("we don't know what they saw"),
|
||||||
|
* not something to backfill with today's config values.
|
||||||
|
*/
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->timestamp('terms_accepted_at')->nullable()->after('otp_attempts');
|
||||||
|
$table->string('terms_version')->nullable()->after('terms_accepted_at');
|
||||||
|
$table->string('privacy_policy_version')->nullable()->after('terms_version');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('users', function (Blueprint $table) {
|
||||||
|
$table->dropColumn(['terms_accepted_at', 'terms_version', 'privacy_policy_version']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Modules\Core\Auth\Listeners;
|
||||||
|
|
||||||
|
use Modules\Core\Auth\Events\UserCreated;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The storefront login page shows a terms/privacy notice ("By continuing,
|
||||||
|
* you accept the Terms of Use and have read the Privacy Policy") that
|
||||||
|
* requesting an OTP code implicitly accepts — recorded once, right here,
|
||||||
|
* for a genuinely new signup only (UserCreated fires exactly once per
|
||||||
|
* user, from Auth\Services\UserOtpService::generateAndSend()'s own
|
||||||
|
* wasRecentlyCreated check). An existing user's original acceptance
|
||||||
|
* (whatever version was live when THEY signed up) must never be
|
||||||
|
* overwritten by whatever config('legal.*') says today, which is exactly
|
||||||
|
* why this only ever runs from UserCreated and nowhere else.
|
||||||
|
*/
|
||||||
|
class RecordLegalAcceptanceForNewUser
|
||||||
|
{
|
||||||
|
public function handle(UserCreated $event): void
|
||||||
|
{
|
||||||
|
$event->user->forceFill([
|
||||||
|
'terms_accepted_at' => now(),
|
||||||
|
'terms_version' => config('legal.terms_version'),
|
||||||
|
'privacy_policy_version' => config('legal.privacy_policy_version'),
|
||||||
|
])->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,6 +66,9 @@ class CustomerDataProvider implements PersonalDataProvider
|
|||||||
'id' => $user->id,
|
'id' => $user->id,
|
||||||
'name' => $user->name,
|
'name' => $user->name,
|
||||||
'email' => $user->email,
|
'email' => $user->email,
|
||||||
|
'terms_accepted_at' => $user->terms_accepted_at,
|
||||||
|
'terms_version' => $user->terms_version,
|
||||||
|
'privacy_policy_version' => $user->privacy_policy_version,
|
||||||
'customers' => $user->customers->map(fn (Customer $customer) => [
|
'customers' => $user->customers->map(fn (Customer $customer) => [
|
||||||
'id' => $customer->id,
|
'id' => $customer->id,
|
||||||
'company_name' => $customer->company_name,
|
'company_name' => $customer->company_name,
|
||||||
|
|||||||
@@ -2,13 +2,18 @@
|
|||||||
|
|
||||||
namespace Modules\Core\Providers;
|
namespace Modules\Core\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
use Modules\Core\Auth\Events\UserCreated;
|
||||||
|
use Modules\Core\Auth\Listeners\RecordLegalAcceptanceForNewUser;
|
||||||
use Modules\Core\Command\CreateAdminCommand;
|
use Modules\Core\Command\CreateAdminCommand;
|
||||||
|
|
||||||
class AuthServiceProvider extends ServiceProvider
|
class AuthServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
|
Event::listen(UserCreated::class, RecordLegalAcceptanceForNewUser::class);
|
||||||
|
|
||||||
if ($this->app->runningInConsole()) {
|
if ($this->app->runningInConsole()) {
|
||||||
$this->app->booted(fn () => $this->commands([CreateAdminCommand::class]));
|
$this->app->booted(fn () => $this->commands([CreateAdminCommand::class]));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user