feat: add rate limiting, case-insensitive usernames and session security
This commit is contained in:
@@ -43,7 +43,15 @@ class CompleteProfileController extends Controller
|
||||
}
|
||||
|
||||
$request->validate([
|
||||
'username' => ['required', 'string', 'max:255', 'alpha_dash', 'unique:'.User::class],
|
||||
'username' => [
|
||||
'required', 'string', 'max:255', 'alpha_dash',
|
||||
function ($attribute, $value, $fail) {
|
||||
$exists = User::whereRaw('LOWER(username) = ?', [strtolower($value)])->exists();
|
||||
if ($exists) {
|
||||
$fail('The username has already been taken.');
|
||||
}
|
||||
},
|
||||
],
|
||||
'first_name' => ['required', 'string', 'max:255'],
|
||||
'last_name' => ['required', 'string', 'max:255'],
|
||||
]);
|
||||
@@ -62,6 +70,7 @@ class CompleteProfileController extends Controller
|
||||
event(new Registered($user));
|
||||
|
||||
Auth::login($user, remember: true);
|
||||
$request->session()->regenerate();
|
||||
|
||||
return redirect()->intended(config('auth-ui.redirects.login', '/'));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,15 @@ class RegisterController extends Controller
|
||||
}
|
||||
|
||||
$request->validate([
|
||||
'username' => ['required', 'string', 'max:255', 'alpha_dash', 'unique:'.User::class],
|
||||
'username' => [
|
||||
'required', 'string', 'max:255', 'alpha_dash',
|
||||
function ($attribute, $value, $fail) {
|
||||
$exists = User::whereRaw('LOWER(username) = ?', [strtolower($value)])->exists();
|
||||
if ($exists) {
|
||||
$fail('The username has already been taken.');
|
||||
}
|
||||
},
|
||||
],
|
||||
'first_name' => ['required', 'string', 'max:255'],
|
||||
'last_name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
|
||||
|
||||
@@ -79,7 +79,7 @@ class SocialiteController extends Controller
|
||||
$suggestedUsername = $this->suggestUsername($socialUser);
|
||||
|
||||
// Check if username is already taken
|
||||
if (User::where('username', $suggestedUsername)->exists()) {
|
||||
if (User::whereRaw('LOWER(username) = ?', [strtolower($suggestedUsername)])->exists()) {
|
||||
// Store social data in session and redirect to complete profile
|
||||
session()->put('socialite_user', [
|
||||
'email' => $socialUser->getEmail(),
|
||||
@@ -103,6 +103,7 @@ class SocialiteController extends Controller
|
||||
}
|
||||
|
||||
Auth::login($user, remember: true);
|
||||
request()->session()->regenerate();
|
||||
|
||||
return redirect()->intended(config('auth-ui.redirects.login', '/'));
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class HandleInertiaRequests extends Middleware
|
||||
'message' => fn () => $request->session()->get('message'),
|
||||
'status' => fn () => $request->session()->get('status'),
|
||||
],
|
||||
'authConfig' => $this->getAuthConfig(),
|
||||
'authConfig' => fn () => $this->getAuthConfig(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -10,16 +10,16 @@ use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::middleware('guest')->group(function () {
|
||||
Route::get('login', [LoginController::class, 'create'])->name('login');
|
||||
Route::post('login', [LoginController::class, 'store']);
|
||||
Route::post('login', [LoginController::class, 'store'])->middleware('throttle:5,1');
|
||||
|
||||
Route::get('register', [RegisterController::class, 'create'])->name('register');
|
||||
Route::post('register', [RegisterController::class, 'store']);
|
||||
Route::post('register', [RegisterController::class, 'store'])->middleware('throttle:3,60');
|
||||
|
||||
Route::get('forgot-password', [ForgotPasswordController::class, 'create'])->name('password.request');
|
||||
Route::post('forgot-password', [ForgotPasswordController::class, 'store'])->name('password.email');
|
||||
Route::post('forgot-password', [ForgotPasswordController::class, 'store'])->name('password.email')->middleware('throttle:3,15');
|
||||
|
||||
Route::get('reset-password/{token}', [ResetPasswordController::class, 'create'])->name('password.reset');
|
||||
Route::post('reset-password', [ResetPasswordController::class, 'store'])->name('password.store');
|
||||
Route::post('reset-password', [ResetPasswordController::class, 'store'])->name('password.store')->middleware('throttle:5,15');
|
||||
|
||||
// Socialite routes
|
||||
Route::get('auth/{provider}', [SocialiteController::class, 'redirect'])->name('socialite.redirect');
|
||||
|
||||
Reference in New Issue
Block a user