mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-24 15:42:09 +08:00
Mix v6 & use RateLimiter Facade vs. trait
This commit is contained in:
Vendored
+8
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-4
@@ -1,6 +1,4 @@
|
||||
{
|
||||
"/js/filament.js": "/js/filament.js?id=9995e728ce8648b81f5d",
|
||||
"/css/filament.css": "/css/filament.css?id=93f842bce37befef5606",
|
||||
"/js/filament.js.map": "/js/filament.js.map?id=1d3615b89069bfd79261",
|
||||
"/css/filament.css.map": "/css/filament.css.map?id=2d1bc71ec284f1c1be4a"
|
||||
"/js/filament.js": "/js/filament.js?id=575bb8a26dd76080eafa",
|
||||
"/css/filament.css": "/css/filament.css?id=ea771d027184eb0863c0"
|
||||
}
|
||||
|
||||
Generated
+4558
-4170
File diff suppressed because it is too large
Load Diff
+14
-15
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "filament",
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "npm run development -- --watch",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"dev": "mix",
|
||||
"watch": "mix watch",
|
||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "mix watch --hot",
|
||||
"prod": "mix --production",
|
||||
"start": "npm run watch"
|
||||
},
|
||||
"author": {
|
||||
@@ -14,24 +14,23 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.5.4",
|
||||
"alpinejs": "^2.7.3",
|
||||
"@popperjs/core": "^2.6.0",
|
||||
"alpinejs": "^2.8.0",
|
||||
"focus-visible": "^5.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.2.1",
|
||||
"@tailwindcss/typography": "^0.3.1",
|
||||
"autoprefixer": "^9.8.6",
|
||||
"browser-sync": "^2.26.13",
|
||||
"browser-sync-webpack-plugin": "^2.2.2",
|
||||
"cross-env": "^7.0.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^8.2.0",
|
||||
"laravel-mix": "^5.0.9",
|
||||
"postcss-import": "^12.0.1",
|
||||
"postcss-nested": "^4.2.3",
|
||||
"prettier": "^2.2.0",
|
||||
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.1",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
"laravel-mix": "^6.0.0",
|
||||
"postcss": "^8.2.1",
|
||||
"postcss-import": "^14.0.0",
|
||||
"postcss-nested": "^5.0.3",
|
||||
"prettier": "^2.2.1",
|
||||
"tailwindcss": "^2.0.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "^2.2.1"
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require('postcss-import'),
|
||||
require('tailwindcss'),
|
||||
require('postcss-nested'),
|
||||
],
|
||||
}
|
||||
@@ -2,14 +2,17 @@
|
||||
|
||||
namespace Filament\Http\Livewire\Auth;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\{
|
||||
RateLimiter,
|
||||
Auth,
|
||||
Route,
|
||||
};
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Auth\Events\Lockout;
|
||||
use Livewire\Component;
|
||||
use Filament\Facades\Filament;
|
||||
use Filament\Traits\ThrottlesLogins;
|
||||
use Filament\Fields\{
|
||||
Text,
|
||||
Checkbox,
|
||||
@@ -17,8 +20,6 @@ use Filament\Fields\{
|
||||
|
||||
class Login extends Component
|
||||
{
|
||||
use ThrottlesLogins;
|
||||
|
||||
public $message;
|
||||
public $email;
|
||||
public $password;
|
||||
@@ -79,21 +80,19 @@ class Login extends Component
|
||||
*/
|
||||
public function submit(Request $request)
|
||||
{
|
||||
$this->ensureIsNotRateLimited($request);
|
||||
|
||||
$data = $this->validate();
|
||||
|
||||
if ($this->hasTooManyLoginAttempts($request)) {
|
||||
$this->fireLockoutEvent($request);
|
||||
|
||||
return $this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
if (Auth::attempt($data, (bool) $this->remember)) {
|
||||
RateLimiter::clear($this->throttleKey());
|
||||
|
||||
return redirect()->intended(Filament::home());
|
||||
}
|
||||
|
||||
$this->incrementLoginAttempts($request);
|
||||
RateLimiter::hit($this->throttleKey());
|
||||
|
||||
$this->addError('password', __('auth.failed'));
|
||||
$this->addError('email', __('auth.failed'));
|
||||
}
|
||||
|
||||
public function render(): \Illuminate\View\View
|
||||
@@ -101,4 +100,39 @@ class Login extends Component
|
||||
return view('filament::livewire.auth.login')
|
||||
->layout('filament::layouts.auth', ['title' => __('filament::auth.signin')]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the login request is not rate limited.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
protected function ensureIsNotRateLimited(Request $request)
|
||||
{
|
||||
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event(new Lockout($request));
|
||||
|
||||
$seconds = RateLimiter::availableIn($this->throttleKey());
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => trans('auth.throttle', [
|
||||
'seconds' => $seconds,
|
||||
'minutes' => ceil($seconds / 60),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rate limiting throttle key for the request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function throttleKey()
|
||||
{
|
||||
return Str::lower($this->email.'|'.request()->ip());
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Traits;
|
||||
|
||||
use Illuminate\Auth\Events\Lockout;
|
||||
use Illuminate\Cache\RateLimiter;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
trait ThrottlesLogins
|
||||
{
|
||||
/**
|
||||
* Determine if the user has too many failed login attempts.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasTooManyLoginAttempts(Request $request)
|
||||
{
|
||||
return $this->limiter()->tooManyAttempts(
|
||||
$this->throttleKey($request), $this->maxAttempts()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the login attempts for the user.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
*/
|
||||
protected function incrementLoginAttempts(Request $request)
|
||||
{
|
||||
$this->limiter()->hit(
|
||||
$this->throttleKey($request), $this->decayMinutes() * 60
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect the user after determining they are locked out.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
protected function sendLockoutResponse(Request $request)
|
||||
{
|
||||
$seconds = $this->limiter()->availableIn(
|
||||
$this->throttleKey($request)
|
||||
);
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => [Lang::get('auth.throttle', [
|
||||
'seconds' => $seconds,
|
||||
'minutes' => ceil($seconds / 60),
|
||||
])],
|
||||
])->status(Response::HTTP_TOO_MANY_REQUESTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the login locks for the given user credentials.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
*/
|
||||
protected function clearLoginAttempts(Request $request)
|
||||
{
|
||||
$this->limiter()->clear($this->throttleKey($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event when a lockout occurs.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
*/
|
||||
protected function fireLockoutEvent(Request $request)
|
||||
{
|
||||
event(new Lockout($request));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the throttle key for the given request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string
|
||||
*/
|
||||
protected function throttleKey(Request $request)
|
||||
{
|
||||
return Str::lower($request->input('email')).'|'.$request->ip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rate limiter instance.
|
||||
*
|
||||
* @return \Illuminate\Cache\RateLimiter
|
||||
*/
|
||||
protected function limiter()
|
||||
{
|
||||
return app(RateLimiter::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum number of attempts to allow.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function maxAttempts()
|
||||
{
|
||||
return property_exists($this, 'maxAttempts') ? $this->maxAttempts : 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of minutes to throttle for.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function decayMinutes()
|
||||
{
|
||||
return property_exists($this, 'decayMinutes') ? $this->decayMinutes : 1;
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ class LoginTest extends TestCase
|
||||
public function test_bad_credentials_show_error()
|
||||
{
|
||||
$this->invalid_login()
|
||||
->assertHasErrors('password');
|
||||
->assertHasErrors('email');
|
||||
}
|
||||
|
||||
public function test_bad_credentials_show_error_due_to_login_throttling()
|
||||
@@ -83,7 +83,7 @@ class LoginTest extends TestCase
|
||||
|
||||
// 5th invalid login attempt should return validation error
|
||||
$this->invalid_login()
|
||||
->assertHasErrors('password');
|
||||
->assertHasErrors('email');
|
||||
}
|
||||
|
||||
private function invalid_login()
|
||||
|
||||
+1
-6
@@ -32,12 +32,7 @@ mix.js(`${SRC}/js/filament.js`, 'js')
|
||||
*
|
||||
* @link https://laravel.com/docs/master/mix#postcss
|
||||
*/
|
||||
mix.postCss(`${SRC}/css/filament.css`, 'css', [
|
||||
require('postcss-import'),
|
||||
require('tailwindcss'),
|
||||
require('postcss-nested'),
|
||||
require('autoprefixer'),
|
||||
])
|
||||
mix.postCss(`${SRC}/css/filament.css`, 'css')
|
||||
|
||||
/**
|
||||
* Sourcemaps
|
||||
|
||||
Reference in New Issue
Block a user