From c0866d4cb33e398f19c7c1c7f4720fe8c98e2cb4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:38:05 +0200 Subject: [PATCH] fix(auth): preserve invite login with database sessions --- app/Http/Controllers/Controller.php | 3 ++- tests/Feature/InvitationLinkHandlingTest.php | 22 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index a567c6244..c723d811a 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -138,10 +138,11 @@ public function link() } $invitation->delete(); - Auth::login($user); $user->forceFill([ 'password' => Hash::make(Str::random(64)), ])->save(); + + Auth::login($user); session(['currentTeam' => $team]); return redirect()->route('dashboard'); diff --git a/tests/Feature/InvitationLinkHandlingTest.php b/tests/Feature/InvitationLinkHandlingTest.php index 184dfd77f..3b473f60e 100644 --- a/tests/Feature/InvitationLinkHandlingTest.php +++ b/tests/Feature/InvitationLinkHandlingTest.php @@ -9,6 +9,7 @@ use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\Crypt; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Once; use Visus\Cuid2\Cuid2; @@ -91,6 +92,27 @@ function createInvitationLinkFixture(array $invitationAttributes = []): array expect(Hash::check($password, $user->password))->toBeFalse(); }); +it('keeps the invited user authenticated after rotating the temporary password with database sessions', function () { + $this->withMiddleware([CheckForcePasswordReset::class, DecideWhatToDoWithUser::class]); + Config::set('session.driver', 'database'); + + [$team, $user, $password, $token] = createInvitationLinkFixture(); + + $this->get(route('auth.link', ['token' => $token])) + ->assertRedirect(route('dashboard')); + + expect(DB::table('sessions')->where('user_id', $user->id)->exists())->toBeTrue(); + + $this->get(route('dashboard')) + ->assertRedirect(route('auth.force-password-reset')); + + $this->assertAuthenticatedAs($user); + expect($user->teams()->where('team_id', $team->id)->exists())->toBeTrue(); + + $user->refresh(); + expect(Hash::check($password, $user->password))->toBeFalse(); +}); + it('rejects a magic link when the stored invitation token differs', function () { [, $user, , $token, $invitation] = createInvitationLinkFixture(); $differentToken = Crypt::encryptString("{$user->email}@@@{$invitation->uuid}@@@different-password");