diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index f76536fab..eb4ca7672 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -5,6 +5,7 @@ use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\RedirectResponse; +use Illuminate\Http\Request; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; @@ -44,6 +45,14 @@ public function __construct() $this->middleware('guest')->except('logout'); } + protected function validateLogin(Request $request): void + { + $request->validate([ + $this->username() => 'required|string', + 'password' => 'required|string|max:72', + ]); + } + /** * Redirect the user to the GitHub authentication page. */ diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 2a6524b1b..2a8cfd678 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -50,7 +50,7 @@ protected function validator(array $data): \Illuminate\Contracts\Validation\Vali return Validator::make($data, [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', - 'password' => Password::defaults(), + 'password' => ['required', 'string', Password::defaults()], 'privacy' => 'required', ]); } diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index cf726eecd..6ead274a5 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -4,6 +4,7 @@ use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ResetsPasswords; +use Illuminate\Validation\Rules\Password; class ResetPasswordController extends Controller { @@ -36,4 +37,16 @@ public function __construct() { $this->middleware('guest'); } + + /** + * @return array + */ + protected function rules(): array + { + return [ + 'token' => 'required', + 'email' => 'required|email', + 'password' => ['required', 'string', 'confirmed', Password::defaults()], + ]; + } } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 999317448..92cb98595 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -39,6 +39,7 @@ public function boot(): void ->mixedCase() ->numbers() ->symbols() + ->max(72) ->uncompromised(); }); diff --git a/resources/js/components/PasswordField.vue b/resources/js/components/PasswordField.vue index 552299e55..aabf23619 100644 --- a/resources/js/components/PasswordField.vue +++ b/resources/js/components/PasswordField.vue @@ -8,6 +8,7 @@ :type="type" :defaultValue="value" :required="required" + maxlength="72" />
post('/register', [ + 'name' => 'Test User', + 'email' => 'long-password@example.com', + 'password' => Str::repeat('Aa1!', 19), // 76 chars + 'password_confirmation' => Str::repeat('Aa1!', 19), + 'privacy' => '1', + ]); + + $response->assertSessionHasErrors('password'); + $this->assertDatabaseMissing('users', ['email' => 'long-password@example.com']); + } + + public function test_login_rejects_password_longer_than_72_characters(): void + { + $response = $this->post('/login', [ + 'email' => 'user@example.com', + 'password' => Str::repeat('x', 73), + ]); + + $response->assertSessionHasErrors('password'); + } + + public function test_registration_page_renders_password_fields(): void + { + $response = $this->get('/register'); + + $response->assertOk(); + $response->assertSee('name="password"', false); + $response->assertSee('name="password_confirmation"', false); + } + + public function test_registration_accepts_password_at_max_length(): void + { + $password = Str::repeat('Aa1!', 18); // 72 chars, meets complexity rules + $this->assertSame(72, strlen($password)); + + $response = $this->post('/register', [ + 'name' => 'Test User', + 'email' => 'max-length@example.com', + 'password' => $password, + 'password_confirmation' => $password, + 'privacy' => '1', + ]); + + $response->assertSessionDoesntHaveErrors(['password']); + } +}