feat(auth): block reserved identifiers at sign-up

Add App\Rules\ReservedIdentifier for name + email local-part so users
cannot impersonate staff (admin, superadmin, support, root, takeone, …).
Separators are collapsed so "super_admin"/"super-admin"/"superadmin"
all match. Rule wired into RegisteredUserController@store.

email_verified_at is already absent from User::$fillable so only the
signed verification route can flip it — audited, no code change needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
This commit is contained in:
ghassanandClaude Opus 4.7 committed 2026-10-21 00:34:32 +03:00
1 parent 56b6a83b34
commit a1493462f7
2 files changed
+59 -2

No files matched your search

@@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
use App\Models\User;
use App\Notifications\NewUserRegistered;
use App\Rules\NotDisposableEmail;
use App\Rules\ReservedIdentifier;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
@@ -27,8 +28,8 @@ class RegisteredUserController extends Controller
}
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users', new NotDisposableEmail],
'name' => ['required', 'string', 'max:255', new ReservedIdentifier('name')],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users', new NotDisposableEmail, new ReservedIdentifier('email')],
'password' => ['required', 'confirmed', Password::defaults()],
'birthday' => ['required', 'date', 'before:today'],
'gender' => ['required', 'in:male,female'],