From 465f077a9fd26c0161064791752364d5bf694e40 Mon Sep 17 00:00:00 2001 From: red Date: Thu, 4 Dec 2025 13:23:19 +0000 Subject: [PATCH] init2 --- app/Livewire/Counter.php | 13 ---- app/Livewire/Participant.php | 13 ---- app/Providers/FortifyServiceProvider.php | 67 +++++++++++++++++ composer.json | 4 +- composer.lock | 4 +- .../views/components/layouts/app.blade.php | 4 + .../views/livewire/pages/profile.blade.php | 20 +++++ .../livewire/{ => pages}/start.blade.php | 3 + .../{ => livewire/pages}/withdraw.blade.php | 0 resources/views/livewire/profile.blade.php | 1 - routes/web.php | 8 +- tests/Feature/Auth/AuthenticationTest.php | 69 ----------------- tests/Feature/Auth/EmailVerificationTest.php | 67 ----------------- .../Feature/Auth/PasswordConfirmationTest.php | 11 --- tests/Feature/Auth/PasswordResetTest.php | 60 --------------- tests/Feature/Auth/RegistrationTest.php | 21 ------ tests/Feature/Auth/TwoFactorChallengeTest.php | 32 -------- tests/Feature/DashboardTest.php | 16 ---- tests/Feature/Settings/PasswordUpdateTest.php | 39 ---------- tests/Feature/Settings/ProfileUpdateTest.php | 75 ------------------- .../Settings/TwoFactorAuthenticationTest.php | 70 ----------------- 21 files changed, 103 insertions(+), 494 deletions(-) delete mode 100644 app/Livewire/Counter.php delete mode 100644 app/Livewire/Participant.php create mode 100644 app/Providers/FortifyServiceProvider.php create mode 100644 resources/views/livewire/pages/profile.blade.php rename resources/views/livewire/{ => pages}/start.blade.php (96%) rename resources/views/{ => livewire/pages}/withdraw.blade.php (100%) delete mode 100644 resources/views/livewire/profile.blade.php delete mode 100644 tests/Feature/Auth/AuthenticationTest.php delete mode 100644 tests/Feature/Auth/EmailVerificationTest.php delete mode 100644 tests/Feature/Auth/PasswordConfirmationTest.php delete mode 100644 tests/Feature/Auth/PasswordResetTest.php delete mode 100644 tests/Feature/Auth/RegistrationTest.php delete mode 100644 tests/Feature/Auth/TwoFactorChallengeTest.php delete mode 100644 tests/Feature/DashboardTest.php delete mode 100644 tests/Feature/Settings/PasswordUpdateTest.php delete mode 100644 tests/Feature/Settings/ProfileUpdateTest.php delete mode 100644 tests/Feature/Settings/TwoFactorAuthenticationTest.php diff --git a/app/Livewire/Counter.php b/app/Livewire/Counter.php deleted file mode 100644 index bc638b3..0000000 --- a/app/Livewire/Counter.php +++ /dev/null @@ -1,13 +0,0 @@ - $request]); + }); + + Fortify::verifyEmailView(function () { + return view('auth.verify-email'); + }); + + Fortify::confirmPasswordView(function () { + return view('auth.password-confirm'); + }); + + Fortify::twoFactorChallengeView(function () { + return view('auth.two-factor-challenge'); + }); + } +} diff --git a/composer.json b/composer.json index 8128296..4ae469b 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "license": "MIT", "require": { "php": "^8.2", - "laravel/fortify": "^1.30", + "laravel/fortify": "^1.32", "laravel/framework": "^12.0", "laravel/tinker": "^2.10.1", "livewire/flux": "^2.9.0", @@ -90,4 +90,4 @@ }, "minimum-stability": "stable", "prefer-stable": true -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock index eafeaa2..e0c6d15 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "23346ce4888d3f652c3a83e0bb6f8827", + "content-hash": "dfe0e74063033164e5069fc96d3bb510", "packages": [ { "name": "bacon/bacon-qr-code", @@ -9837,5 +9837,5 @@ "php": "^8.2" }, "platform-dev": {}, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/resources/views/components/layouts/app.blade.php b/resources/views/components/layouts/app.blade.php index 89ba46c..5df0928 100644 --- a/resources/views/components/layouts/app.blade.php +++ b/resources/views/components/layouts/app.blade.php @@ -1,3 +1,7 @@ +@livewireStyles + {{ $slot }} + +@livewireScripts diff --git a/resources/views/livewire/pages/profile.blade.php b/resources/views/livewire/pages/profile.blade.php new file mode 100644 index 0000000..7fa3e1d --- /dev/null +++ b/resources/views/livewire/pages/profile.blade.php @@ -0,0 +1,20 @@ + 0, + 'user' => Participant::find($token), +]); + +$increment = fn () => $this->count++; + +?> + +
+

User: {{$user?->name ?? 'Not found'}}

+
diff --git a/resources/views/livewire/start.blade.php b/resources/views/livewire/pages/start.blade.php similarity index 96% rename from resources/views/livewire/start.blade.php rename to resources/views/livewire/pages/start.blade.php index e987106..368539e 100644 --- a/resources/views/livewire/start.blade.php +++ b/resources/views/livewire/pages/start.blade.php @@ -1,3 +1,5 @@ + @@ -30,3 +32,4 @@ +@endsection diff --git a/resources/views/withdraw.blade.php b/resources/views/livewire/pages/withdraw.blade.php similarity index 100% rename from resources/views/withdraw.blade.php rename to resources/views/livewire/pages/withdraw.blade.php diff --git a/resources/views/livewire/profile.blade.php b/resources/views/livewire/profile.blade.php deleted file mode 100644 index b3d9bbc..0000000 --- a/resources/views/livewire/profile.blade.php +++ /dev/null @@ -1 +0,0 @@ -name('home'); +Volt::route('start', 'pages.start')->name('start'); +Volt::route('profile', 'pages.profile')->name('profile'); +Volt::route('withdraw', 'pages.withdraw')->name('withdraw'); + Route::middleware(['auth'])->group(function () { - Volt::route('start', 'start')->name('start'); - Volt::route('profile', 'profile')->name('profile'); - Volt::route('withdraw', 'withdraw')->name('withdraw'); + }); diff --git a/tests/Feature/Auth/AuthenticationTest.php b/tests/Feature/Auth/AuthenticationTest.php deleted file mode 100644 index 3107856..0000000 --- a/tests/Feature/Auth/AuthenticationTest.php +++ /dev/null @@ -1,69 +0,0 @@ -get(route('login')); - - $response->assertStatus(200); -}); - -test('users can authenticate using the login screen', function () { - $user = User::factory()->withoutTwoFactor()->create(); - - $response = $this->post(route('login.store'), [ - 'email' => $user->email, - 'password' => 'password', - ]); - - $response - ->assertSessionHasNoErrors() - ->assertRedirect(route('dashboard', absolute: false)); - - $this->assertAuthenticated(); -}); - -test('users can not authenticate with invalid password', function () { - $user = User::factory()->create(); - - $response = $this->post(route('login.store'), [ - 'email' => $user->email, - 'password' => 'wrong-password', - ]); - - $response->assertSessionHasErrorsIn('email'); - - $this->assertGuest(); -}); - -test('users with two factor enabled are redirected to two factor challenge', function () { - if (! Features::canManageTwoFactorAuthentication()) { - $this->markTestSkipped('Two-factor authentication is not enabled.'); - } - - Features::twoFactorAuthentication([ - 'confirm' => true, - 'confirmPassword' => true, - ]); - - $user = User::factory()->create(); - - $response = $this->post(route('login.store'), [ - 'email' => $user->email, - 'password' => 'password', - ]); - - $response->assertRedirect(route('two-factor.login')); - $this->assertGuest(); -}); - -test('users can logout', function () { - $user = User::factory()->create(); - - $response = $this->actingAs($user)->post(route('logout')); - - $response->assertRedirect(route('home')); - - $this->assertGuest(); -}); \ No newline at end of file diff --git a/tests/Feature/Auth/EmailVerificationTest.php b/tests/Feature/Auth/EmailVerificationTest.php deleted file mode 100644 index b4994c9..0000000 --- a/tests/Feature/Auth/EmailVerificationTest.php +++ /dev/null @@ -1,67 +0,0 @@ -unverified()->create(); - - $response = $this->actingAs($user)->get(route('verification.notice')); - - $response->assertStatus(200); -}); - -test('email can be verified', function () { - $user = User::factory()->unverified()->create(); - - Event::fake(); - - $verificationUrl = URL::temporarySignedRoute( - 'verification.verify', - now()->addMinutes(60), - ['id' => $user->id, 'hash' => sha1($user->email)] - ); - - $response = $this->actingAs($user)->get($verificationUrl); - - Event::assertDispatched(Verified::class); - - expect($user->fresh()->hasVerifiedEmail())->toBeTrue(); - $response->assertRedirect(route('dashboard', absolute: false).'?verified=1'); -}); - -test('email is not verified with invalid hash', function () { - $user = User::factory()->unverified()->create(); - - $verificationUrl = URL::temporarySignedRoute( - 'verification.verify', - now()->addMinutes(60), - ['id' => $user->id, 'hash' => sha1('wrong-email')] - ); - - $this->actingAs($user)->get($verificationUrl); - - expect($user->fresh()->hasVerifiedEmail())->toBeFalse(); -}); - -test('already verified user visiting verification link is redirected without firing event again', function () { - $user = User::factory()->create([ - 'email_verified_at' => now(), - ]); - - Event::fake(); - - $verificationUrl = URL::temporarySignedRoute( - 'verification.verify', - now()->addMinutes(60), - ['id' => $user->id, 'hash' => sha1($user->email)] - ); - - $this->actingAs($user)->get($verificationUrl) - ->assertRedirect(route('dashboard', absolute: false).'?verified=1'); - - expect($user->fresh()->hasVerifiedEmail())->toBeTrue(); - Event::assertNotDispatched(Verified::class); -}); \ No newline at end of file diff --git a/tests/Feature/Auth/PasswordConfirmationTest.php b/tests/Feature/Auth/PasswordConfirmationTest.php deleted file mode 100644 index de14aae..0000000 --- a/tests/Feature/Auth/PasswordConfirmationTest.php +++ /dev/null @@ -1,11 +0,0 @@ -create(); - - $response = $this->actingAs($user)->get(route('password.confirm')); - - $response->assertStatus(200); -}); \ No newline at end of file diff --git a/tests/Feature/Auth/PasswordResetTest.php b/tests/Feature/Auth/PasswordResetTest.php deleted file mode 100644 index b1224ce..0000000 --- a/tests/Feature/Auth/PasswordResetTest.php +++ /dev/null @@ -1,60 +0,0 @@ -get(route('password.request')); - - $response->assertStatus(200); -}); - -test('reset password link can be requested', function () { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post(route('password.request'), ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class); -}); - -test('reset password screen can be rendered', function () { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post(route('password.request'), ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class, function ($notification) { - $response = $this->get(route('password.reset', $notification->token)); - - $response->assertStatus(200); - - return true; - }); -}); - -test('password can be reset with valid token', function () { - Notification::fake(); - - $user = User::factory()->create(); - - $this->post(route('password.request'), ['email' => $user->email]); - - Notification::assertSentTo($user, ResetPassword::class, function ($notification) use ($user) { - $response = $this->post(route('password.update'), [ - 'token' => $notification->token, - 'email' => $user->email, - 'password' => 'password', - 'password_confirmation' => 'password', - ]); - - $response - ->assertSessionHasNoErrors() - ->assertRedirect(route('login', absolute: false)); - - return true; - }); -}); \ No newline at end of file diff --git a/tests/Feature/Auth/RegistrationTest.php b/tests/Feature/Auth/RegistrationTest.php deleted file mode 100644 index 075f695..0000000 --- a/tests/Feature/Auth/RegistrationTest.php +++ /dev/null @@ -1,21 +0,0 @@ -get(route('register')); - - $response->assertStatus(200); -}); - -test('new users can register', function () { - $response = $this->post(route('register.store'), [ - 'name' => 'John Doe', - 'email' => 'test@example.com', - 'password' => 'password', - 'password_confirmation' => 'password', - ]); - - $response->assertSessionHasNoErrors() - ->assertRedirect(route('dashboard', absolute: false)); - - $this->assertAuthenticated(); -}); \ No newline at end of file diff --git a/tests/Feature/Auth/TwoFactorChallengeTest.php b/tests/Feature/Auth/TwoFactorChallengeTest.php deleted file mode 100644 index c4be01f..0000000 --- a/tests/Feature/Auth/TwoFactorChallengeTest.php +++ /dev/null @@ -1,32 +0,0 @@ -markTestSkipped('Two-factor authentication is not enabled.'); - } - - $response = $this->get(route('two-factor.login')); - - $response->assertRedirect(route('login')); -}); - -test('two factor challenge can be rendered', function () { - if (! Features::canManageTwoFactorAuthentication()) { - $this->markTestSkipped('Two-factor authentication is not enabled.'); - } - - Features::twoFactorAuthentication([ - 'confirm' => true, - 'confirmPassword' => true, - ]); - - $user = User::factory()->create(); - - $this->post(route('login.store'), [ - 'email' => $user->email, - 'password' => 'password', - ])->assertRedirect(route('two-factor.login')); -}); \ No newline at end of file diff --git a/tests/Feature/DashboardTest.php b/tests/Feature/DashboardTest.php deleted file mode 100644 index 7290183..0000000 --- a/tests/Feature/DashboardTest.php +++ /dev/null @@ -1,16 +0,0 @@ -get(route('dashboard')); - $response->assertRedirect(route('login')); -}); - -test('authenticated users can visit the dashboard', function () { - $user = User::factory()->create(); - $this->actingAs($user); - - $response = $this->get(route('dashboard')); - $response->assertStatus(200); -}); \ No newline at end of file diff --git a/tests/Feature/Settings/PasswordUpdateTest.php b/tests/Feature/Settings/PasswordUpdateTest.php deleted file mode 100644 index 2af6939..0000000 --- a/tests/Feature/Settings/PasswordUpdateTest.php +++ /dev/null @@ -1,39 +0,0 @@ -create([ - 'password' => Hash::make('password'), - ]); - - $this->actingAs($user); - - $response = Volt::test('settings.password') - ->set('current_password', 'password') - ->set('password', 'new-password') - ->set('password_confirmation', 'new-password') - ->call('updatePassword'); - - $response->assertHasNoErrors(); - - expect(Hash::check('new-password', $user->refresh()->password))->toBeTrue(); -}); - -test('correct password must be provided to update password', function () { - $user = User::factory()->create([ - 'password' => Hash::make('password'), - ]); - - $this->actingAs($user); - - $response = Volt::test('settings.password') - ->set('current_password', 'wrong-password') - ->set('password', 'new-password') - ->set('password_confirmation', 'new-password') - ->call('updatePassword'); - - $response->assertHasErrors(['current_password']); -}); \ No newline at end of file diff --git a/tests/Feature/Settings/ProfileUpdateTest.php b/tests/Feature/Settings/ProfileUpdateTest.php deleted file mode 100644 index 01e6d75..0000000 --- a/tests/Feature/Settings/ProfileUpdateTest.php +++ /dev/null @@ -1,75 +0,0 @@ -actingAs($user = User::factory()->create()); - - $this->get(route('profile.edit'))->assertOk(); -}); - -test('profile information can be updated', function () { - $user = User::factory()->create(); - - $this->actingAs($user); - - $response = Volt::test('settings.profile') - ->set('name', 'Test User') - ->set('email', 'test@example.com') - ->call('updateProfileInformation'); - - $response->assertHasNoErrors(); - - $user->refresh(); - - expect($user->name)->toEqual('Test User'); - expect($user->email)->toEqual('test@example.com'); - expect($user->email_verified_at)->toBeNull(); -}); - -test('email verification status is unchanged when email address is unchanged', function () { - $user = User::factory()->create(); - - $this->actingAs($user); - - $response = Volt::test('settings.profile') - ->set('name', 'Test User') - ->set('email', $user->email) - ->call('updateProfileInformation'); - - $response->assertHasNoErrors(); - - expect($user->refresh()->email_verified_at)->not->toBeNull(); -}); - -test('user can delete their account', function () { - $user = User::factory()->create(); - - $this->actingAs($user); - - $response = Volt::test('settings.delete-user-form') - ->set('password', 'password') - ->call('deleteUser'); - - $response - ->assertHasNoErrors() - ->assertRedirect('/'); - - expect($user->fresh())->toBeNull(); - expect(auth()->check())->toBeFalse(); -}); - -test('correct password must be provided to delete account', function () { - $user = User::factory()->create(); - - $this->actingAs($user); - - $response = Volt::test('settings.delete-user-form') - ->set('password', 'wrong-password') - ->call('deleteUser'); - - $response->assertHasErrors(['password']); - - expect($user->fresh())->not->toBeNull(); -}); \ No newline at end of file diff --git a/tests/Feature/Settings/TwoFactorAuthenticationTest.php b/tests/Feature/Settings/TwoFactorAuthenticationTest.php deleted file mode 100644 index c913976..0000000 --- a/tests/Feature/Settings/TwoFactorAuthenticationTest.php +++ /dev/null @@ -1,70 +0,0 @@ -markTestSkipped('Two-factor authentication is not enabled.'); - } - - Features::twoFactorAuthentication([ - 'confirm' => true, - 'confirmPassword' => true, - ]); -}); - -test('two factor settings page can be rendered', function () { - $user = User::factory()->withoutTwoFactor()->create(); - - $this->actingAs($user) - ->withSession(['auth.password_confirmed_at' => time()]) - ->get(route('two-factor.show')) - ->assertOk() - ->assertSee('Two Factor Authentication') - ->assertSee('Disabled'); -}); - -test('two factor settings page requires password confirmation when enabled', function () { - $user = User::factory()->create(); - - $response = $this->actingAs($user) - ->get(route('two-factor.show')); - - $response->assertRedirect(route('password.confirm')); -}); - -test('two factor settings page returns forbidden response when two factor is disabled', function () { - config(['fortify.features' => []]); - - $user = User::factory()->create(); - - $response = $this->actingAs($user) - ->withSession(['auth.password_confirmed_at' => time()]) - ->get(route('two-factor.show')); - - $response->assertForbidden(); -}); - -test('two factor authentication disabled when confirmation abandoned between requests', function () { - $user = User::factory()->create(); - - $user->forceFill([ - 'two_factor_secret' => encrypt('test-secret'), - 'two_factor_recovery_codes' => encrypt(json_encode(['code1', 'code2'])), - 'two_factor_confirmed_at' => null, - ])->save(); - - $this->actingAs($user); - - $component = Volt::test('settings.two-factor'); - - $component->assertSet('twoFactorEnabled', false); - - $this->assertDatabaseHas('users', [ - 'id' => $user->id, - 'two_factor_secret' => null, - 'two_factor_recovery_codes' => null, - ]); -}); \ No newline at end of file