feat: make user password nullable for social-only accounts

This commit is contained in:
2026-03-19 23:14:57 +01:00
parent 44c1cbe5f6
commit 10f612a901
3 changed files with 72 additions and 6 deletions

View File

@@ -2,17 +2,18 @@
namespace App\Models; namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail; use Database\Factories\UserFactory;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable; use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable class User extends Authenticatable implements MustVerifyEmail
{ {
/** @use HasFactory<\Database\Factories\UserFactory> */ /** @use HasFactory<UserFactory> */
use HasApiTokens, HasFactory, Notifiable; use HasFactory, Notifiable;
/** /**
* The attributes that are mass assignable. * The attributes that are mass assignable.
@@ -59,6 +60,32 @@ class User extends Authenticatable
]; ];
} }
/**
* Only send verification notification when the feature is enabled.
*/
public function sendEmailVerificationNotification(): void
{
if (config('auth-ui.features.email_verification')) {
parent::sendEmailVerificationNotification();
}
}
/**
* Check if the user has a password set (i.e. not a social-only user).
*/
public function hasPassword(): bool
{
return $this->password !== null;
}
/**
* Get the user's social accounts.
*/
public function socialAccounts(): HasMany
{
return $this->hasMany(SocialAccount::class);
}
/** /**
* Get the user's full name. * Get the user's full name.
*/ */

View File

@@ -2,12 +2,13 @@
namespace Database\Factories; namespace Database\Factories;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str; use Illuminate\Support\Str;
/** /**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User> * @extends Factory<User>
*/ */
class UserFactory extends Factory class UserFactory extends Factory
{ {
@@ -43,4 +44,14 @@ class UserFactory extends Factory
'email_verified_at' => null, 'email_verified_at' => null,
]); ]);
} }
/**
* Indicate that the user was created via social login (no password).
*/
public function social(): static
{
return $this->state(fn (array $attributes) => [
'password' => null,
]);
}
} }

View File

@@ -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->string('password')->nullable()->change();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('password')->nullable(false)->change();
});
}
};