feat: accept terms
This commit is contained in:
@@ -360,6 +360,7 @@ class AuthController extends Controller
|
||||
$userAttributes['email'] = strtolower($data['email']);
|
||||
$userAttributes['password'] = Hash::make($data['password']);
|
||||
$userAttributes['avatar_url'] = $avatarPath;
|
||||
$userAttributes['terms_accepted_at'] = now();
|
||||
$trialDays = max(0, (int) config('billing.trial_days', 7));
|
||||
|
||||
if ($trialDays > 0) {
|
||||
|
||||
@@ -50,6 +50,7 @@ class RegisterRequest extends FormRequest
|
||||
->symbols()
|
||||
->uncompromised(),
|
||||
],
|
||||
'termsAccepted' => ['required', 'accepted'],
|
||||
'avatar' => ['sometimes', 'nullable', 'image', 'max:2048'],
|
||||
'bio' => ['nullable', 'string'],
|
||||
'physicalActivityLevel' => ['sometimes', Rule::enum(PhysicalActivityLevel::class)],
|
||||
|
||||
@@ -58,6 +58,7 @@ class User extends Authenticatable implements FilamentUser, HasAvatar, HasLocale
|
||||
'pace_preference',
|
||||
'sex',
|
||||
'date_of_birth',
|
||||
'terms_accepted_at',
|
||||
'suspended_at',
|
||||
'suspended_by',
|
||||
'suspended_reason',
|
||||
@@ -95,6 +96,7 @@ class User extends Authenticatable implements FilamentUser, HasAvatar, HasLocale
|
||||
'sex' => UserSex::class,
|
||||
'role' => UserRole::class,
|
||||
'date_of_birth' => 'immutable_date',
|
||||
'terms_accepted_at' => 'datetime',
|
||||
'suspended_at' => 'datetime',
|
||||
'trial_ends_at' => 'datetime',
|
||||
];
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->timestampTz('terms_accepted_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('terms_accepted_at');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -27,6 +27,7 @@ it('sends a verification email when a user registers', function () {
|
||||
'pacePreference' => PacePreference::NORMAL->value,
|
||||
'sex' => UserSex::WOMAN->value,
|
||||
'dateOfBirth' => '2003-04-24',
|
||||
'termsAccepted' => true,
|
||||
])
|
||||
->assertCreated()
|
||||
->assertJsonPath('user.email', 'leon@example.com')
|
||||
@@ -45,7 +46,8 @@ it('sends a verification email when a user registers', function () {
|
||||
|
||||
expect($user->hasVerifiedEmail())->toBeFalse()
|
||||
->and($user->trial_ends_at)->not->toBeNull()
|
||||
->and($user->trial_ends_at->isFuture())->toBeTrue();
|
||||
->and($user->trial_ends_at->isFuture())->toBeTrue()
|
||||
->and($user->terms_accepted_at)->not->toBeNull();
|
||||
|
||||
$this->assertDatabaseHas('users', [
|
||||
'id' => $user->id,
|
||||
@@ -71,6 +73,7 @@ it('returns a temporary error when the verification email cannot be sent during
|
||||
'email' => 'leon@example.com',
|
||||
'password' => 'Motsdfdepasse123*',
|
||||
'locale' => 'fr-FR',
|
||||
'termsAccepted' => true,
|
||||
])
|
||||
->assertServiceUnavailable()
|
||||
->assertJsonPath('message', __('api.auth.verification_email_failed'));
|
||||
@@ -94,6 +97,7 @@ it('registers mobile users with a bearer token', function () {
|
||||
'pacePreference' => PacePreference::NORMAL->value,
|
||||
'sex' => UserSex::MAN->value,
|
||||
'dateOfBirth' => '2003-04-24',
|
||||
'termsAccepted' => true,
|
||||
])
|
||||
->assertCreated()
|
||||
->assertJsonPath('user.email', 'mobile.leon@example.com')
|
||||
@@ -111,6 +115,31 @@ it('registers mobile users with a bearer token', function () {
|
||||
Notification::assertSentTo($user, VerifyEmail::class);
|
||||
});
|
||||
|
||||
it('requires users to accept the terms during registration', function () {
|
||||
Notification::fake();
|
||||
|
||||
$registrationData = [
|
||||
'name' => 'TermsLeon',
|
||||
'email' => 'terms.leon@example.com',
|
||||
'password' => 'Motsdfdepasse123*',
|
||||
'termsAccepted' => false,
|
||||
];
|
||||
|
||||
$this->postJson('/api/auth/mobile/register', $registrationData)
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('termsAccepted');
|
||||
|
||||
unset($registrationData['termsAccepted']);
|
||||
|
||||
$this->postJson('/api/auth/mobile/register', $registrationData)
|
||||
->assertUnprocessable()
|
||||
->assertJsonValidationErrors('termsAccepted');
|
||||
|
||||
$this->assertDatabaseMissing('users', [
|
||||
'email' => 'terms.leon@example.com',
|
||||
]);
|
||||
});
|
||||
|
||||
it('uses the custom account verification mailable', function () {
|
||||
$user = User::factory()->unverified()->create([
|
||||
'locale' => 'fr',
|
||||
|
||||
Reference in New Issue
Block a user