This repository has been archived on 2024-05-20. You can view files and clone it, but cannot push or open issues or pull requests.

137 lines
4.3 KiB
PHP

<?php
use App\Models\Log;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Rule;
use Livewire\Volt\Component;
new #[Layout('layouts.guest')] class extends Component
{
#[Rule(['required', 'string', 'email'])]
public string $email = '';
#[Rule(['required', 'string'])]
public string $password = '';
#[Rule(['boolean'])]
public bool $remember = false;
public function login(): void
{
$this->validate();
$this->ensureIsNotRateLimited();
if (!auth()->attempt($this->only(['email', 'password'], $this->remember))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
session()->regenerate();
activity()
->performedOn(auth()->user())
->event('access')
->log('User logged in');
$this->redirect(
session('url.intended', RouteServiceProvider::HOME),
navigate: true
);
}
protected function ensureIsNotRateLimited(): void
{
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),
]),
]);
}
protected function throttleKey(): string
{
return Str::transliterate(Str::lower($this->email) . '|' . request()->ip());
}
}; ?>
<div class="w-full sm:max-w-md mt-6 px-6 py-4 overflow-hidden">
<!-- Session Status -->
<x-auth-session-status class="mb-4" :status="session('status')"/>
<form wire:submit="login">
<!-- Email Address -->
<div>
<x-input-label for="email" :value="__('Email')"/>
<x-text-input wire:model="email"
id="email"
class="block mt-1 w-full"
type="email"
name="email"
required
autofocus
autocomplete="username"/>
<x-input-error :messages="$errors->get('email')" class="mt-2"/>
</div>
<!-- Password -->
<div class="mt-4">
<x-input-label for="password" :value="__('Password')"/>
<x-text-input wire:model="password" id="password" class="block mt-1 w-full"
type="password"
name="password"
required autocomplete="current-password"/>
<x-input-error :messages="$errors->get('password')" class="mt-2"/>
</div>
<!-- Remember Me -->
<div class="block mt-4">
<label for="remember" class="inline-flex items-center">
<input wire:model="remember"
id="remember"
type="checkbox"
class="rounded border-gray-300 dark:border-gray-700 text-nexi-red shadow-sm focus:ring-nexi-red"
name="remember">
<span class="ml-2 text-sm text-gray-600 dark:text-gray-300">{{ __('Remember me') }}</span>
</label>
</div>
<div class="flex items-center justify-end mt-4">
@if (Route::has('password.request'))
<a class="underline text-sm text-gray-600 dark:text-gray-300 hover:text-nexi-black dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-nexi-red"
href="{{ route('password.request') }}"
wire:navigate>
{{ __('Forgot your password?') }}
</a>
@endif
<x-primary-button wire:loading.attr="disabled" wire:loading.class="opacity-50" class="ml-3">
{{ __('Log in') }}
</x-primary-button>
</div>
</form>
</div>