Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beautify Livewire Stack #326

Merged
merged 10 commits into from
Oct 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Console/InstallsLivewireStack.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ protected function installLivewireStack($functional = false)
(new Filesystem)->ensureDirectoryExists(app_path('View/Components'));
(new Filesystem)->copyDirectory(__DIR__.'/../../stubs/default/app/View/Components', app_path('View/Components'));

// Actions...
(new Filesystem)->ensureDirectoryExists(app_path('Livewire/Actions'));
(new Filesystem)->copyDirectory(__DIR__.'/../../stubs/livewire-common/app/Livewire/Actions', app_path('Livewire/Actions'));

// Forms...
(new Filesystem)->ensureDirectoryExists(app_path('Livewire/Forms'));
(new Filesystem)->copyDirectory(__DIR__.'/../../stubs/livewire-common/app/Livewire/Forms', app_path('Livewire/Forms'));

// Dark mode...
if (! $this->option('dark')) {
$this->removeDarkClasses((new Finder)
Expand Down
20 changes: 20 additions & 0 deletions stubs/livewire-common/app/Livewire/Actions/Logout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Livewire\Actions;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;

class Logout
{
/**
* Log the current user out of the application.
*/
public function __invoke(): void
{
Auth::guard('web')->logout();

Session::invalidate();
Session::regenerateToken();
}
}
72 changes: 72 additions & 0 deletions stubs/livewire-common/app/Livewire/Forms/LoginForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

namespace App\Livewire\Forms;

use Illuminate\Auth\Events\Lockout;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Livewire\Attributes\Rule;
use Livewire\Form;

class LoginForm extends Form
{
#[Rule('required|string|email')]
public string $email = '';

#[Rule('required|string')]
public string $password = '';

#[Rule('boolean')]
public bool $remember = false;

/**
* Attempt to authenticate the request's credentials.
*
* @throws \Illuminate\Validation\ValidationException
*/
public function authenticate(): void
{
$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());
}

/**
* Ensure the authentication request is not rate limited.
*/
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),
]),
]);
}

/**
* Get the authentication rate limiting throttle key.
*/
protected function throttleKey(): string
{
return Str::transliterate(Str::lower($this->email).'|'.request()->ip());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
$user = User::factory()->create();

$component = Volt::test('pages.auth.login')
->set('email', $user->email)
->set('password', 'password');
->set('form.email', $user->email)
->set('form.password', 'password');

$component->call('login');

Expand All @@ -32,8 +32,8 @@
$user = User::factory()->create();

$component = Volt::test('pages.auth.login')
->set('email', $user->email)
->set('password', 'wrong-password');
->set('form.email', $user->email)
->set('form.password', 'wrong-password');

$component->call('login');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public function test_users_can_authenticate_using_the_login_screen(): void
$user = User::factory()->create();

$component = Volt::test('pages.auth.login')
->set('email', $user->email)
->set('password', 'password');
->set('form.email', $user->email)
->set('form.password', 'password');

$component->call('login');

Expand All @@ -43,8 +43,8 @@ public function test_users_can_not_authenticate_with_invalid_password(): void
$user = User::factory()->create();

$component = Volt::test('pages.auth.login')
->set('email', $user->email)
->set('password', 'wrong-password');
->set('form.email', $user->email)
->set('form.password', 'wrong-password');

$component->call('login');

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
<?php

$logout = function () {
auth()->guard('web')->logout();
use App\Livewire\Actions\Logout;

session()->invalidate();
session()->regenerateToken();
$logout = function (Logout $logout) {
$logout();
Comment on lines +5 to +6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$logout = function (Logout $logout) {
$logout();
$logout = function (Logout $logoutAction) {
$logoutAction();

In my opinion it is a bad idea to have the same name for the callback and action, because I thought the Closure is calling itself.


$this->redirect('/', navigate: true);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use App\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;

use function Livewire\Volt\layout;
Expand All @@ -16,8 +17,8 @@
$confirmPassword = function () {
$this->validate();

if (! auth()->guard('web')->validate([
'email' => auth()->user()->email,
if (! Auth::guard('web')->validate([
'email' => Auth::user()->email,
'password' => $this->password,
])) {
throw ValidationException::withMessages([
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Session;

use function Livewire\Volt\layout;
use function Livewire\Volt\rules;
Expand Down Expand Up @@ -30,7 +31,7 @@

$this->reset('email');

session()->flash('status', __($status));
Session::flash('status', __($status));
};

?>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,22 @@
<?php

use App\Livewire\Forms\LoginForm;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Session;

use function Livewire\Volt\form;
use function Livewire\Volt\layout;
use function Livewire\Volt\rules;
use function Livewire\Volt\state;

layout('layouts.guest');

state(['email' => '', 'password' => '', 'remember' => false]);

rules([
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
'remember' => ['boolean'],
]);
form(LoginForm::class);

$login = function () {
$this->validate();

$throttleKey = Str::transliterate(Str::lower($this->email).'|'.request()->ip());

if (RateLimiter::tooManyAttempts($throttleKey, 5)) {
event(new Lockout(request()));

$seconds = RateLimiter::availableIn($throttleKey);

throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}

if (! auth()->attempt($this->only(['email', 'password']), $this->remember)) {
RateLimiter::hit($throttleKey);

throw ValidationException::withMessages([
'email' => trans('auth.failed'),
]);
}

RateLimiter::clear($throttleKey);
$this->form->authenticate();

session()->regenerate();
Session::regenerate();

$this->redirect(
session('url.intended', RouteServiceProvider::HOME),
Expand All @@ -66,15 +34,15 @@
<!-- 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-text-input wire:model="form.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"
<x-text-input wire:model="form.password" id="password" class="block mt-1 w-full"
type="password"
name="password"
required autocomplete="current-password" />
Expand All @@ -85,7 +53,7 @@
<!-- 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 dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800" name="remember">
<input wire:model="form.remember" id="remember" type="checkbox" class="rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800" name="remember">
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">{{ __('Remember me') }}</span>
</label>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;

use function Livewire\Volt\layout;
use function Livewire\Volt\rules;
use function Livewire\Volt\state;
Expand All @@ -31,7 +33,7 @@

event(new Registered($user = User::create($validated)));

auth()->login($user);
Auth::login($user);

$this->redirect(RouteServiceProvider::HOME, navigate: true);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Str;
use Illuminate\Validation\Rules;

Expand Down Expand Up @@ -53,7 +54,7 @@ function ($user) {
return;
}

session()->flash('status', __($status));
Session::flash('status', __($status));

$this->redirectRoute('login', navigate: true);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<?php

use App\Livewire\Actions\Logout;
use App\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;

use function Livewire\Volt\layout;

layout('layouts.guest');

$sendVerification = function () {
if (auth()->user()->hasVerifiedEmail()) {
if (Auth::user()->hasVerifiedEmail()) {
$this->redirect(
session('url.intended', RouteServiceProvider::HOME),
navigate: true
Expand All @@ -16,16 +19,13 @@
return;
}

auth()->user()->sendEmailVerificationNotification();
Auth::user()->sendEmailVerificationNotification();

session()->flash('status', 'verification-link-sent');
Session::flash('status', 'verification-link-sent');
};

$logout = function () {
auth()->guard('web')->logout();

session()->invalidate();
session()->regenerateToken();
$logout = function (Logout $logout) {
$logout();
Comment on lines +27 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$logout = function (Logout $logout) {
$logout();
$logout = function (Logout $logoutAction) {
$logoutAction();


$this->redirect('/', navigate: true);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
<?php

use App\Livewire\Actions\Logout;
use Illuminate\Support\Facades\Auth;

use function Livewire\Volt\rules;
use function Livewire\Volt\state;

state(['password' => '']);

rules(['password' => ['required', 'string', 'current_password']]);

$deleteUser = function () {
$deleteUser = function (Logout $logout) {
$this->validate();

tap(auth()->user(), fn () => auth()->logout())->delete();

session()->invalidate();
session()->regenerateToken();
tap(Auth::user(), $logout(...))->delete();

$this->redirect('/', navigate: true);
};
Expand Down
Loading