mirror of https://github.com/MarceauKa/shaark.git
🔖 1.2.4
This commit is contained in:
parent
5b2e6f9e56
commit
7637c2b506
|
@ -2,19 +2,28 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Login;
|
||||
use App\Notifications\SecureLoginCode;
|
||||
use App\SecureLogin;
|
||||
use App\User;
|
||||
use Illuminate\Auth\Events\Failed;
|
||||
use Illuminate\Auth\SessionGuard;
|
||||
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Lab404\AuthChecker\Services\AuthChecker;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use ThrottlesLogins;
|
||||
|
||||
public $maxAttempts = 5;
|
||||
public $decayMinutes = 1;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('guest')->except('logout');
|
||||
|
||||
$this->middleware('throttle:5,1')->only('check');
|
||||
}
|
||||
|
||||
public function form()
|
||||
|
@ -29,21 +38,57 @@ class LoginController extends Controller
|
|||
'password' => 'required|string',
|
||||
]);
|
||||
|
||||
if ($this->hasTooManyLoginAttempts($request)) {
|
||||
$this->fireLockoutEvent($request);
|
||||
$this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
if (true === app('shaarli')->getSecureLogin()) {
|
||||
return $this->checkWithSecureLogin($request, $validated);
|
||||
}
|
||||
|
||||
return $this->checkWithoutSecureLogin($request, $validated);
|
||||
}
|
||||
|
||||
protected function checkWithoutSecureLogin(Request $request, array $validated)
|
||||
{
|
||||
if (Auth::guard()->attempt($validated, $request->filled('remember'))) {
|
||||
$request->session()->regenerate();
|
||||
|
||||
if (true === app('shaarli')->getSecureLogin()) {
|
||||
$user = Auth::guard()->user();
|
||||
$secure = SecureLogin::createForUser($user);
|
||||
$user->notify(new SecureLoginCode($secure));
|
||||
Auth::logout();
|
||||
|
||||
return redirect()->route('login.secure', $secure);
|
||||
}
|
||||
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => [__("Invalid credentials")],
|
||||
]);
|
||||
}
|
||||
|
||||
protected function checkWithSecureLogin(Request $request, array $validated)
|
||||
{
|
||||
/** @var SessionGuard $guard */
|
||||
$guard = Auth::guard();
|
||||
|
||||
if ($guard->validate($validated)) {
|
||||
/** @var User $user */
|
||||
$user = $guard->getLastAttempted();
|
||||
|
||||
/** @var AuthChecker $checker */
|
||||
$checker = app('authchecker');
|
||||
$device = $checker->findOrCreateUserDeviceByAgent($user);
|
||||
$checker->createUserLoginForDevice($user, $device, Login::TYPE_2FA);
|
||||
|
||||
$secure = SecureLogin::createForUser($user);
|
||||
$user->notify(new SecureLoginCode($secure));
|
||||
|
||||
return redirect()->route('login.secure', $secure);
|
||||
}
|
||||
|
||||
event(new Failed('web', $guard->getLastAttempted(), $validated));
|
||||
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => [__("Invalid credentials")],
|
||||
]);
|
||||
|
@ -57,4 +102,9 @@ class LoginController extends Controller
|
|||
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
public function username(): string
|
||||
{
|
||||
return 'email';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Lab404\AuthChecker\Models\Login as BaseLogin;
|
||||
|
||||
class Login extends BaseLogin
|
||||
{
|
||||
const TYPE_2FA = '2fa';
|
||||
}
|
|
@ -29,8 +29,8 @@ class SecureLoginCode extends Notification
|
|||
{
|
||||
return (new MailMessage)
|
||||
->subject(__("Secure your login"))
|
||||
->line(__("Please use the following code to access your account."))
|
||||
->action($this->secure->code, sprintf('%s?code=%s', route('login.secure', $this->secure), $this->secure->code));
|
||||
->line(__("Please use the following code :code to access your account.", ['code' => $this->secure->code]))
|
||||
->action(__("Confirm login"), sprintf('%s?code=%s', route('login.secure', $this->secure), $this->secure->code));
|
||||
}
|
||||
|
||||
public function toArray($notifiable)
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
@ -33,7 +34,11 @@ class SecureLogin extends Model
|
|||
return 'token';
|
||||
}
|
||||
|
||||
public static function createForUser(User $user): self
|
||||
/**
|
||||
* @param Authenticatable|User $user
|
||||
* @return static
|
||||
*/
|
||||
public static function createForUser($user): self
|
||||
{
|
||||
$code_length = app('shaarli')->getSecureCodeLength();
|
||||
$expire_minutes = app('shaarli')->getSecureCodeExpires();
|
||||
|
|
|
@ -15,7 +15,7 @@ use Spatie\Valuestore\Valuestore;
|
|||
class Shaarli
|
||||
{
|
||||
/** @var string VERSION */
|
||||
public const VERSION = '1.2.3';
|
||||
public const VERSION = '1.2.4';
|
||||
/** @var Application $app */
|
||||
protected $app;
|
||||
/** @var Valuestore $settings */
|
||||
|
|
14
changelog.md
14
changelog.md
|
@ -1,3 +1,17 @@
|
|||
# 1.2.4
|
||||
|
||||
## Changed
|
||||
|
||||
- LoginController throttles request
|
||||
- AuthChecker now handles 2FA
|
||||
- Secure login email notification CTA and message
|
||||
|
||||
## Fixed
|
||||
|
||||
- Secure Login don't log failed attempts
|
||||
- Use `request()->input('code')` instead of `request('code')` in secure login form
|
||||
- Story form confirm message i18n
|
||||
|
||||
# 1.2.3
|
||||
|
||||
## Added
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use App\Login;
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|
@ -60,7 +62,7 @@ return [
|
|||
# Ex: App\Models\Device (default: Lab404\AuthChecker\Models\Device)
|
||||
'device' => null,
|
||||
# Ex: App\Models\Login (default: Lab404\AuthChecker\Models\Login)
|
||||
'login' => null,
|
||||
'login' => Login::class,
|
||||
]
|
||||
|
||||
];
|
||||
|
|
|
@ -128,10 +128,10 @@ export default {
|
|||
data: this.form
|
||||
}).then((response) => {
|
||||
if (this.story) {
|
||||
this.$toasted.success(this.__("Story updated !"));
|
||||
this.$toasted.success(this.__("Story updated"));
|
||||
this.loading = false;
|
||||
} else {
|
||||
this.$toasted.success(this.__("Story created !"));
|
||||
this.$toasted.success(this.__("Story created"));
|
||||
this.reset();
|
||||
}
|
||||
}).catch((error) => {
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
"Invalid secure code": "Code de sécurité invalide",
|
||||
"A security code has been sent to you. This code will expire :expire.": "Un code de sécurité vous a été envoyé. Il expirera :expire.",
|
||||
"Secure your login": "Sécurisez votre connexion",
|
||||
"Please use the following code to access your account.": "Veuillez utiliser le code suivant pour sécuriser votre connexion.",
|
||||
"Please use the following code :code to access your account.": "Veuillez utiliser le code suivant :code pour sécuriser votre connexion.",
|
||||
"Confirm login": "Confirmer la connexion",
|
||||
|
||||
"Manage": "Gestion",
|
||||
"Page": "Page",
|
||||
|
@ -157,6 +158,7 @@
|
|||
"Date": "Date",
|
||||
"Status": "Statut",
|
||||
"Succeeded": "Réussie",
|
||||
"2FA": "2FA",
|
||||
"Locked": "Bloquée",
|
||||
"Failed": "Échouée",
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<label for="code" class="col-md-4 col-form-label text-md-right">{{ __('Secure code') }}</label>
|
||||
|
||||
<div class="col-md-6">
|
||||
<input id="code" type="text" class="form-control @error('code') is-invalid @enderror" name="code" value="{{ request('code') }}" required autofocus>
|
||||
<input id="code" type="text" class="form-control @error('code') is-invalid @enderror" name="code" value="{{ request()->input('code') }}" required autofocus>
|
||||
|
||||
@error('code')
|
||||
<span class="invalid-feedback" role="alert">
|
||||
|
|
|
@ -41,11 +41,13 @@
|
|||
</td>
|
||||
<td class="align-middle">{{ $login->created_at->diffForHumans() }}</td>
|
||||
<td class="align-middle">
|
||||
@if($login->type === \Lab404\AuthChecker\Models\Login::TYPE_LOGIN)
|
||||
@if($login->type === App\Login::TYPE_LOGIN)
|
||||
<span class="badge badge-success">{{ __('Succeeded') }}</span>
|
||||
@elseif($login->type === \Lab404\AuthChecker\Models\Login::TYPE_LOCKOUT)
|
||||
@elseif($login->type === App\Login::TYPE_2FA)
|
||||
<span class="badge badge-warning">{{ __('2FA') }}</span>
|
||||
@elseif($login->type === App\Login::TYPE_LOCKOUT)
|
||||
<span class="badge badge-danger">{{ __('Locked') }}</span>
|
||||
@else
|
||||
@elseif($login->type === App\Login::TYPE_FAILED)
|
||||
<span class="badge badge-danger">{{ __('Failed') }}</span>
|
||||
@endif
|
||||
</td>
|
||||
|
|
Loading…
Reference in New Issue