Merge pull request #6628 from heavygee/fix/team-invitation-email-case-sensitivity

Fix team invitation email case sensitivity bug
This commit is contained in:
Andras Bacsai 2025-09-25 09:29:24 +02:00 committed by GitHub
commit 3f71f7becf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 113 additions and 1 deletions

View file

@ -10,6 +10,7 @@
use App\Traits\HasNotificationSettings;
use App\Traits\HasSafeStringAttribute;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use OpenApi\Attributes as OA;
@ -37,7 +38,7 @@
class Team extends Model implements SendsDiscord, SendsEmail, SendsPushover, SendsSlack
{
use HasNotificationSettings, HasSafeStringAttribute, Notifiable;
use HasFactory, HasNotificationSettings, HasSafeStringAttribute, Notifiable;
protected $guarded = [];

View file

@ -15,6 +15,14 @@ class TeamInvitation extends Model
'via',
];
/**
* Set the email attribute to lowercase.
*/
public function setEmailAttribute($value)
{
$this->attributes['email'] = strtolower($value);
}
public function team()
{
return $this->belongsTo(Team::class);

View file

@ -0,0 +1,40 @@
<?php
namespace Database\Factories;
use App\Models\Team;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Team>
*/
class TeamFactory extends Factory
{
protected $model = Team::class;
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => $this->faker->company() . ' Team',
'description' => $this->faker->sentence(),
'personal_team' => false,
'show_boarding' => false,
];
}
/**
* Indicate that the team is a personal team.
*/
public function personal(): static
{
return $this->state(fn (array $attributes) => [
'personal_team' => true,
'name' => $this->faker->firstName() . "'s Team",
]);
}
}

View file

@ -0,0 +1,63 @@
<?php
namespace Tests\Feature;
use App\Models\Team;
use App\Models\TeamInvitation;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class TeamInvitationEmailNormalizationTest extends TestCase
{
use RefreshDatabase;
public function test_team_invitation_normalizes_email_to_lowercase()
{
// Create a team
$team = Team::factory()->create();
// Create invitation with mixed case email
$invitation = TeamInvitation::create([
'team_id' => $team->id,
'uuid' => 'test-uuid-123',
'email' => 'Test@Example.com', // Mixed case
'role' => 'member',
'link' => 'https://example.com/invite/test-uuid-123',
'via' => 'link'
]);
// Verify email was normalized to lowercase
$this->assertEquals('test@example.com', $invitation->email);
}
public function test_team_invitation_works_with_existing_user_email()
{
// Create a team
$team = Team::factory()->create();
// Create a user with lowercase email
$user = User::factory()->create([
'email' => 'test@example.com',
'name' => 'Test User'
]);
// Create invitation with mixed case email
$invitation = TeamInvitation::create([
'team_id' => $team->id,
'uuid' => 'test-uuid-123',
'email' => 'Test@Example.com', // Mixed case
'role' => 'member',
'link' => 'https://example.com/invite/test-uuid-123',
'via' => 'link'
]);
// Verify the invitation email matches the user email (both normalized)
$this->assertEquals($user->email, $invitation->email);
// Verify user lookup works
$foundUser = User::whereEmail($invitation->email)->first();
$this->assertNotNull($foundUser);
$this->assertEquals($user->id, $foundUser->id);
}
}