From 51e2e5ac0579ce2c03f2f2f84cf9f40d34dc0765 Mon Sep 17 00:00:00 2001 From: Joel Butcher Date: Wed, 11 Oct 2023 13:38:17 +0100 Subject: [PATCH] feat: breeze livewire-functional --- .../Blade/AuthenticateOauthCallback.php | 3 +- .../Auth/Breeze/HandleOauthCallbackErrors.php | 3 +- .../Livewire/AuthenticateOauthCallback.php | 3 +- .../Filament/AuthenticateOauthCallback.php | 3 +- .../Filament/HandleOauthCallbackErrors.php | 3 +- .../Jetstream/AuthenticateOauthCallback.php | 3 +- .../Jetstream/HandleOauthCallbackErrors.php | 3 +- src/Console/InstallCommand.php | 4 +- src/Http/Livewire/SetPasswordForm.php | 5 +- .../Breeze/FunctionalLivewireDriver.php | 72 +++++++++++ .../Drivers/Breeze/LivewireDriver.php | 4 +- src/Installer/Enums/BreezeInstallStack.php | 4 +- src/Installer/InstallManager.php | 7 ++ .../Http/Controllers/ProfileController.php | 3 +- .../Http/Controllers/ProfileController.php | 3 +- .../views/components/socialstream.blade.php | 0 .../resources/views/profile.blade.php | 0 .../routes/auth.php | 0 .../routes/web.php | 0 .../views/livewire/pages/auth/login.blade.php | 105 ++++++++++++++++ .../livewire/pages/auth/register.blade.php | 91 ++++++++++++++ .../profile/connected-accounts-form.blade.php | 117 ++++++++++++++++++ .../pages/profile/delete-user-form.blade.php | 79 ++++++++++++ .../pages/profile/set-password-form.blade.php | 61 +++++++++ .../livewire/pages/auth/register.blade.php | 3 + .../profile/connected-accounts-form.blade.php | 3 +- .../profile/set-password-form.blade.php | 2 +- tests/Unit/InstallerManagerTest.php | 6 + 28 files changed, 561 insertions(+), 29 deletions(-) create mode 100644 src/Installer/Drivers/Breeze/FunctionalLivewireDriver.php rename stubs/breeze/{livewire => livewire-common}/resources/views/components/socialstream.blade.php (100%) rename stubs/breeze/{livewire => livewire-common}/resources/views/profile.blade.php (100%) rename stubs/breeze/{livewire => livewire-common}/routes/auth.php (100%) rename stubs/breeze/{livewire => livewire-common}/routes/web.php (100%) create mode 100644 stubs/breeze/livewire-functional/resources/views/livewire/pages/auth/login.blade.php create mode 100644 stubs/breeze/livewire-functional/resources/views/livewire/pages/auth/register.blade.php create mode 100644 stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/connected-accounts-form.blade.php create mode 100644 stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/delete-user-form.blade.php create mode 100644 stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/set-password-form.blade.php diff --git a/src/Actions/Auth/Breeze/Blade/AuthenticateOauthCallback.php b/src/Actions/Auth/Breeze/Blade/AuthenticateOauthCallback.php index 97e0f81a..1afcb153 100644 --- a/src/Actions/Auth/Breeze/Blade/AuthenticateOauthCallback.php +++ b/src/Actions/Auth/Breeze/Blade/AuthenticateOauthCallback.php @@ -6,7 +6,6 @@ use Illuminate\Contracts\Auth\Guard; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Response; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\MessageBag; use JoelButcher\Socialstream\ConnectedAccount; use JoelButcher\Socialstream\Contracts\AuthenticatesOauthCallback; @@ -36,7 +35,7 @@ public function authenticate(string $provider, ProviderUser $providerAccount): R $account = Socialstream::findConnectedAccountForProviderAndId($provider, $providerAccount->getId()); // Authenticated... - if (! is_null($user = Auth::user())) { + if (! is_null($user = auth()->user())) { return $this->alreadyAuthenticated($user, $account, $provider, $providerAccount); } diff --git a/src/Actions/Auth/Breeze/HandleOauthCallbackErrors.php b/src/Actions/Auth/Breeze/HandleOauthCallbackErrors.php index 450f222f..e3605fa2 100644 --- a/src/Actions/Auth/Breeze/HandleOauthCallbackErrors.php +++ b/src/Actions/Auth/Breeze/HandleOauthCallbackErrors.php @@ -5,7 +5,6 @@ use App\Providers\RouteServiceProvider; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\MessageBag; use JoelButcher\Socialstream\Contracts\HandlesOauthCallbackErrors; @@ -23,7 +22,7 @@ public function handle(Request $request): ?RedirectResponse $messageBag = new MessageBag; $messageBag->add('socialstream', $request->get('error_description')); - return Auth::check() + return auth()->check() ? redirect(RouteServiceProvider::HOME)->withErrors(['callback' => $request->get('error_description')]) : redirect()->route('login')->withErrors($messageBag); } diff --git a/src/Actions/Auth/Breeze/Livewire/AuthenticateOauthCallback.php b/src/Actions/Auth/Breeze/Livewire/AuthenticateOauthCallback.php index 2b4cbec4..86f4aab3 100644 --- a/src/Actions/Auth/Breeze/Livewire/AuthenticateOauthCallback.php +++ b/src/Actions/Auth/Breeze/Livewire/AuthenticateOauthCallback.php @@ -6,7 +6,6 @@ use Illuminate\Contracts\Auth\Guard; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Response; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\MessageBag; use JoelButcher\Socialstream\ConnectedAccount; use JoelButcher\Socialstream\Contracts\AuthenticatesOauthCallback; @@ -36,7 +35,7 @@ public function authenticate(string $provider, ProviderUser $providerAccount): R $account = Socialstream::findConnectedAccountForProviderAndId($provider, $providerAccount->getId()); // Authenticated... - if (! is_null($user = Auth::user())) { + if (! is_null($user = auth()->user())) { return $this->alreadyAuthenticated($user, $account, $provider, $providerAccount); } diff --git a/src/Actions/Auth/Filament/AuthenticateOauthCallback.php b/src/Actions/Auth/Filament/AuthenticateOauthCallback.php index 44286777..49287962 100644 --- a/src/Actions/Auth/Filament/AuthenticateOauthCallback.php +++ b/src/Actions/Auth/Filament/AuthenticateOauthCallback.php @@ -6,7 +6,6 @@ use Illuminate\Contracts\Auth\Guard; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Response; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\MessageBag; use JoelButcher\Socialstream\ConnectedAccount; use JoelButcher\Socialstream\Contracts\AuthenticatesOauthCallback; @@ -36,7 +35,7 @@ public function authenticate(string $provider, ProviderUser $providerAccount): R $account = Socialstream::findConnectedAccountForProviderAndId($provider, $providerAccount->getId()); // Authenticated... - if (! is_null($user = Auth::user())) { + if (! is_null($user = auth()->user())) { return $this->alreadyAuthenticated($user, $account, $provider, $providerAccount); } diff --git a/src/Actions/Auth/Filament/HandleOauthCallbackErrors.php b/src/Actions/Auth/Filament/HandleOauthCallbackErrors.php index 23bb5ee5..70a11e25 100644 --- a/src/Actions/Auth/Filament/HandleOauthCallbackErrors.php +++ b/src/Actions/Auth/Filament/HandleOauthCallbackErrors.php @@ -4,7 +4,6 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\MessageBag; use JoelButcher\Socialstream\Contracts\HandlesOauthCallbackErrors; @@ -22,7 +21,7 @@ public function handle(Request $request): ?RedirectResponse $messageBag = new MessageBag; $messageBag->add('socialstream', $request->get('error_description')); - return Auth::check() + return auth()->check() ? redirect()->route('filament.home')->withErrors($messageBag) : redirect()->route( 'filament.admin.auth.login' diff --git a/src/Actions/Auth/Jetstream/AuthenticateOauthCallback.php b/src/Actions/Auth/Jetstream/AuthenticateOauthCallback.php index 98b9386f..0c9aefc7 100644 --- a/src/Actions/Auth/Jetstream/AuthenticateOauthCallback.php +++ b/src/Actions/Auth/Jetstream/AuthenticateOauthCallback.php @@ -6,7 +6,6 @@ use Illuminate\Contracts\Auth\StatefulGuard; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Response; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\MessageBag; use JoelButcher\Socialstream\ConnectedAccount; use JoelButcher\Socialstream\Contracts\AuthenticatesOauthCallback; @@ -38,7 +37,7 @@ public function authenticate(string $provider, ProviderUser $providerAccount): R $account = Socialstream::findConnectedAccountForProviderAndId($provider, $providerAccount->getId()); // Authenticated... - if (! is_null($user = Auth::user())) { + if (! is_null($user = auth()->user())) { return $this->alreadyAuthenticated($user, $account, $provider, $providerAccount); } diff --git a/src/Actions/Auth/Jetstream/HandleOauthCallbackErrors.php b/src/Actions/Auth/Jetstream/HandleOauthCallbackErrors.php index b4a693b2..6e22c4bb 100644 --- a/src/Actions/Auth/Jetstream/HandleOauthCallbackErrors.php +++ b/src/Actions/Auth/Jetstream/HandleOauthCallbackErrors.php @@ -4,7 +4,6 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\MessageBag; use JoelButcher\Socialstream\Contracts\HandlesOauthCallbackErrors; use Laravel\Fortify\Features as FortifyFeatures; @@ -23,7 +22,7 @@ public function handle(Request $request): ?RedirectResponse $messageBag = new MessageBag; $messageBag->add('socialstream', $request->get('error_description')); - return Auth::check() + return auth()->check() ? redirect(config('fortify.home'))->dangerBanner($request->get('error_description')) : redirect()->route( FortifyFeatures::enabled(FortifyFeatures::registration()) ? 'register' : 'login' diff --git a/src/Console/InstallCommand.php b/src/Console/InstallCommand.php index 15712da8..eca88eb0 100644 --- a/src/Console/InstallCommand.php +++ b/src/Console/InstallCommand.php @@ -61,8 +61,8 @@ public function handle(InstallManager $installManager): ?int { $installManager->driver(match (true) { $this->getStarterKit() === InstallStarterKit::Filament => 'filament', - $this->getStarterKit() === InstallStarterKit::Breeze && - $this->getStack() === BreezeInstallStack::Livewire => 'livewire-breeze', + ($this->getStarterKit() === InstallStarterKit::Breeze && + $this->getStack() === BreezeInstallStack::Livewire) => 'livewire-breeze', default => $this->getStarterKit()->value.'-'.$this->getStack()->value, })->install( $this->option('composer'), diff --git a/src/Http/Livewire/SetPasswordForm.php b/src/Http/Livewire/SetPasswordForm.php index ad0a6a9f..407860c5 100644 --- a/src/Http/Livewire/SetPasswordForm.php +++ b/src/Http/Livewire/SetPasswordForm.php @@ -2,7 +2,6 @@ namespace JoelButcher\Socialstream\Http\Livewire; -use Illuminate\Support\Facades\Auth; use Illuminate\View\View; use JoelButcher\Socialstream\Contracts\SetsUserPasswords; use Livewire\Component; @@ -26,7 +25,7 @@ public function setPassword(SetsUserPasswords $setter): void { $this->resetErrorBag(); - $setter->set(Auth::user(), $this->state); + $setter->set(auth()->user(), $this->state); $this->state = [ 'password' => '', @@ -43,7 +42,7 @@ public function setPassword(SetsUserPasswords $setter): void */ public function getUserProperty(): mixed { - return Auth::user(); + return auth()->user(); } /** diff --git a/src/Installer/Drivers/Breeze/FunctionalLivewireDriver.php b/src/Installer/Drivers/Breeze/FunctionalLivewireDriver.php new file mode 100644 index 00000000..80c8b10b --- /dev/null +++ b/src/Installer/Drivers/Breeze/FunctionalLivewireDriver.php @@ -0,0 +1,72 @@ +copyDirectory(__DIR__.'/../../../../stubs/breeze/default/resources/views/components/socialstream-icons', resource_path('views/components/socialstream-icons')); + + copy(__DIR__.'/../../../../stubs/breeze/default/resources/views/components/action-link.blade.php', resource_path('views/components/action-link.blade.php')); + copy(__DIR__.'/../../../../stubs/breeze/default/resources/views/components/connected-account.blade.php', resource_path('views/components/connected-account.blade.php')); + copy(__DIR__.'/../../../../stubs/breeze/livewire-common/resources/views/components/socialstream.blade.php', resource_path('views/components/socialstream.blade.php')); + + return $this; + } +} diff --git a/src/Installer/Drivers/Breeze/LivewireDriver.php b/src/Installer/Drivers/Breeze/LivewireDriver.php index 0e185341..7445c480 100644 --- a/src/Installer/Drivers/Breeze/LivewireDriver.php +++ b/src/Installer/Drivers/Breeze/LivewireDriver.php @@ -48,7 +48,7 @@ protected function copyAuthViews(InstallOptions ...$options): static */ protected function copyProfileViews(InstallOptions ...$options): static { - copy(__DIR__.'/../../../../stubs/breeze/livewire/resources/views/profile.blade.php', resource_path('views/profile.blade.php')); + copy(__DIR__.'/../../../../stubs/breeze/livewire-common/resources/views/profile.blade.php', resource_path('views/profile.blade.php')); copy(__DIR__.'/../../../../stubs/breeze/livewire/resources/views/livewire/profile/delete-user-form.blade.php', resource_path('views/livewire/profile/delete-user-form.blade.php')); copy(__DIR__.'/../../../../stubs/breeze/livewire/resources/views/livewire/profile/set-password-form.blade.php', resource_path('views/livewire/profile/set-password-form.blade.php')); copy(__DIR__.'/../../../../stubs/breeze/livewire/resources/views/livewire/profile/connected-accounts-form.blade.php', resource_path('views/livewire/profile/connected-accounts-form.blade.php')); @@ -65,7 +65,7 @@ protected function copySocialstreamComponents(InstallOptions ...$options): stati copy(__DIR__.'/../../../../stubs/breeze/default/resources/views/components/action-link.blade.php', resource_path('views/components/action-link.blade.php')); copy(__DIR__.'/../../../../stubs/breeze/default/resources/views/components/connected-account.blade.php', resource_path('views/components/connected-account.blade.php')); - copy(__DIR__.'/../../../../stubs/breeze/livewire/resources/views/components/socialstream.blade.php', resource_path('views/components/socialstream.blade.php')); + copy(__DIR__.'/../../../../stubs/breeze/livewire-common/resources/views/components/socialstream.blade.php', resource_path('views/components/socialstream.blade.php')); return $this; } diff --git a/src/Installer/Enums/BreezeInstallStack.php b/src/Installer/Enums/BreezeInstallStack.php index da987873..d2a963c0 100644 --- a/src/Installer/Enums/BreezeInstallStack.php +++ b/src/Installer/Enums/BreezeInstallStack.php @@ -6,6 +6,7 @@ enum BreezeInstallStack: string { case Blade = 'blade'; case Livewire = 'livewire'; + case FunctionalLivewire = 'livewire-functional'; case React = 'react'; case Vue = 'vue'; @@ -13,7 +14,8 @@ public function label(): string { return match ($this) { self::Blade => 'Blade with Alpine', - self::Livewire => 'Livewire with Alpine', + self::Livewire => 'Livewire (Volt Class API) with Alpine', + self::FunctionalLivewire => 'Livewire (Volt Functional API) with Alpine', self::React => 'React with Inertia', self::Vue => 'Vue with Inertia', }; diff --git a/src/Installer/InstallManager.php b/src/Installer/InstallManager.php index 7943d330..1898d075 100644 --- a/src/Installer/InstallManager.php +++ b/src/Installer/InstallManager.php @@ -4,6 +4,7 @@ use Illuminate\Support\Manager; use JoelButcher\Socialstream\Installer\Drivers\Breeze\BladeDriver; +use JoelButcher\Socialstream\Installer\Drivers\Breeze\FunctionalLivewireDriver as BreezeLivewireFunctionalDriver; use JoelButcher\Socialstream\Installer\Drivers\Breeze\LivewireDriver as BreezeLivewireDriver; use JoelButcher\Socialstream\Installer\Drivers\Breeze\ReactInertiaDriver; use JoelButcher\Socialstream\Installer\Drivers\Breeze\VueInertiaDriver; @@ -32,6 +33,12 @@ public function createBreezeLivewireDriver(): BreezeLivewireDriver return $this->container->make(BreezeLivewireDriver::class); } + public function createBreezeLivewireFunctionalDriver(): BreezeLivewireFunctionalDriver + { + return $this->container->make(BreezeLivewireFunctionalDriver::class); + } + + public function createBreezeReactDriver(): ReactInertiaDriver { return $this->container->make(ReactInertiaDriver::class); diff --git a/stubs/breeze/default/app/Http/Controllers/ProfileController.php b/stubs/breeze/default/app/Http/Controllers/ProfileController.php index 72d88b33..b2fb713b 100644 --- a/stubs/breeze/default/app/Http/Controllers/ProfileController.php +++ b/stubs/breeze/default/app/Http/Controllers/ProfileController.php @@ -5,7 +5,6 @@ use App\Http\Requests\ProfileUpdateRequest; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Redirect; use Illuminate\View\View; @@ -48,7 +47,7 @@ public function destroy(Request $request): RedirectResponse $user = $request->user(); - Auth::logout(); + auth()->logout(); $user->connectedAccounts->each->delete(); $user->delete(); diff --git a/stubs/breeze/inertia-common/app/Http/Controllers/ProfileController.php b/stubs/breeze/inertia-common/app/Http/Controllers/ProfileController.php index 492601c1..5ac236c4 100644 --- a/stubs/breeze/inertia-common/app/Http/Controllers/ProfileController.php +++ b/stubs/breeze/inertia-common/app/Http/Controllers/ProfileController.php @@ -6,7 +6,6 @@ use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Redirect; use Inertia\Inertia; use Inertia\Response; @@ -51,7 +50,7 @@ public function destroy(Request $request): RedirectResponse $user = $request->user(); - Auth::logout(); + auth()->logout(); $user->connectedAccounts->each->delete(); $user->delete(); diff --git a/stubs/breeze/livewire/resources/views/components/socialstream.blade.php b/stubs/breeze/livewire-common/resources/views/components/socialstream.blade.php similarity index 100% rename from stubs/breeze/livewire/resources/views/components/socialstream.blade.php rename to stubs/breeze/livewire-common/resources/views/components/socialstream.blade.php diff --git a/stubs/breeze/livewire/resources/views/profile.blade.php b/stubs/breeze/livewire-common/resources/views/profile.blade.php similarity index 100% rename from stubs/breeze/livewire/resources/views/profile.blade.php rename to stubs/breeze/livewire-common/resources/views/profile.blade.php diff --git a/stubs/breeze/livewire/routes/auth.php b/stubs/breeze/livewire-common/routes/auth.php similarity index 100% rename from stubs/breeze/livewire/routes/auth.php rename to stubs/breeze/livewire-common/routes/auth.php diff --git a/stubs/breeze/livewire/routes/web.php b/stubs/breeze/livewire-common/routes/web.php similarity index 100% rename from stubs/breeze/livewire/routes/web.php rename to stubs/breeze/livewire-common/routes/web.php diff --git a/stubs/breeze/livewire-functional/resources/views/livewire/pages/auth/login.blade.php b/stubs/breeze/livewire-functional/resources/views/livewire/pages/auth/login.blade.php new file mode 100644 index 00000000..108de7f4 --- /dev/null +++ b/stubs/breeze/livewire-functional/resources/views/livewire/pages/auth/login.blade.php @@ -0,0 +1,105 @@ + '', 'password' => '', 'remember' => false]); + +rules([ + 'email' => ['required', 'string', 'email'], + 'password' => ['required', 'string'], + 'remember' => ['boolean'], +]); + +$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); + + session()->regenerate(); + + $this->redirect( + session('url.intended', RouteServiceProvider::HOME), + navigate: true + ); +}; + +?> + +
+ + + +
+ +
+ + + +
+ + +
+ + + + + +
+ + +
+ +
+ +
+ @if (Route::has('password.request')) + + {{ __('Forgot your password?') }} + + @endif + + + {{ __('Log in') }} + +
+
+
diff --git a/stubs/breeze/livewire-functional/resources/views/livewire/pages/auth/register.blade.php b/stubs/breeze/livewire-functional/resources/views/livewire/pages/auth/register.blade.php new file mode 100644 index 00000000..144a7180 --- /dev/null +++ b/stubs/breeze/livewire-functional/resources/views/livewire/pages/auth/register.blade.php @@ -0,0 +1,91 @@ + '', + 'email' => '', + 'password' => '', + 'password_confirmation' => '' +]); + +rules([ + 'name' => ['required', 'string', 'max:255'], + 'email' => ['required', 'string', 'email', 'max:255', 'unique:'.User::class], + 'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()], +]); + +$register = function () { + $validated = $this->validate(); + + $validated['password'] = Hash::make($validated['password']); + + event(new Registered($user = User::create($validated))); + + auth()->login($user); + + $this->redirect(RouteServiceProvider::HOME, navigate: true); +}; + +?> + +
+
+ +
+ + + +
+ + +
+ + + +
+ + +
+ + + + + +
+ + +
+ + + + + +
+ +
+ + {{ __('Already registered?') }} + + + + {{ __('Register') }} + +
+
+
diff --git a/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/connected-accounts-form.blade.php b/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/connected-accounts-form.blade.php new file mode 100644 index 00000000..c2ddb8eb --- /dev/null +++ b/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/connected-accounts-form.blade.php @@ -0,0 +1,117 @@ + '']); + +rules(['password' => ['required', 'string', 'current_password']]); + +$removeAccount = function () { + $this->validate(); + + auth()->user()->connectedAccounts() + ->where('id', $id) + ->delete(); + + $this->redirect(route('profile'), navigate: true); +}; + +?> +
+
+

+ {{ __('Connected Accounts') }} +

+ +

+ {{ __('You are free to connect any social accounts to your profile and may remove any connected accounts at any time. If you feel any of your connected accounts have been compromised, you should disconnect them immediately and change your password.') }} +

+
+ + + +
+ @foreach (JoelButcher\Socialstream\Socialstream::providers() as $provider) + @php + $account = null; + $account = auth()->user()->connectedAccounts->where('provider', $provider)->first(); + @endphp + + + + @if (! is_null($account)) +
+ @if ((auth()->user()->connectedAccounts->count() > 1 || ! is_null(auth()->user()->getAuthPassword()))) + {{ __('Remove') }} + @endif +
+ @else + + {{ __('Connect') }} + + @endif +
+
+ + @if($account) + +
+ @csrf + @method('delete') + +

+ {{ __('Are you sure you want to remove this account?') }} +

+ +

+ {{ __('Please enter your password to confirm you would like to remove this account.') }} +

+ +
+ + + + + +
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Remove Account') }} + +
+
+
+ @endif + @endforeach +
+ + + {{ __('Saved.') }} + + + @if (session('status') === 'connected-account-added') +

{{ __('Account Connected!') }}

+ @endif +
diff --git a/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/delete-user-form.blade.php b/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/delete-user-form.blade.php new file mode 100644 index 00000000..fb8cb6ed --- /dev/null +++ b/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/delete-user-form.blade.php @@ -0,0 +1,79 @@ + '']); + +rules(['password' => ['required', 'string', 'current_password']]); + +$deleteUser = function () { + $this->validate(); + + $user = tap(auth()->user(), fn () => auth()->logout()); + + $user->connectedAccounts->each->delete(); + $user->delete(); + + session()->invalidate(); + session()->regenerateToken(); + + $this->redirect('/', navigate: true); +}; + +?> + +
+
+

+ {{ __('Delete Account') }} +

+ +

+ {{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.') }} +

+
+ + {{ __('Delete Account') }} + + +
+ +

+ {{ __('Are you sure you want to delete your account?') }} +

+ +

+ {{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }} +

+ +
+ + + + + +
+ +
+ + {{ __('Cancel') }} + + + + {{ __('Delete Account') }} + +
+
+
+
diff --git a/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/set-password-form.blade.php b/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/set-password-form.blade.php new file mode 100644 index 00000000..bac99c66 --- /dev/null +++ b/stubs/breeze/livewire-functional/resources/views/livewire/pages/profile/set-password-form.blade.php @@ -0,0 +1,61 @@ + '', 'password_confirmation' => '']); + +rules(['password' => ['required', 'string', 'confirmed', Password::defaults()]]); + +$setPassword = function () { + try { + $validated = $this->validate(); + } catch (ValidationException $e) { + $this->reset('current_password', 'password', 'password_confirmation'); + + throw $e; + } + + auth()->user()->update([ + 'password' => Hash::make($validated['password']), + ]); + + $this->reset('password', 'password_confirmation'); + + redirect()->route('profile'); +}; + +?> + +
+
+

+ {{ __('Set Password') }} +

+ +

+ {{ __('Ensure your account is using a long, random password to stay secure.') }} +

+
+ +
+
+ + + +
+ +
+ + + +
+ + {{ __('Save') }} +
+
diff --git a/stubs/breeze/livewire/resources/views/livewire/pages/auth/register.blade.php b/stubs/breeze/livewire/resources/views/livewire/pages/auth/register.blade.php index 219ecd6f..37668026 100644 --- a/stubs/breeze/livewire/resources/views/livewire/pages/auth/register.blade.php +++ b/stubs/breeze/livewire/resources/views/livewire/pages/auth/register.blade.php @@ -11,8 +11,11 @@ new #[Layout('layouts.guest')] class extends Component { public string $name = ''; + public string $email = ''; + public string $password = ''; + public string $password_confirmation = ''; public function register(): void diff --git a/stubs/breeze/livewire/resources/views/livewire/profile/connected-accounts-form.blade.php b/stubs/breeze/livewire/resources/views/livewire/profile/connected-accounts-form.blade.php index ff96f6e7..31d37270 100644 --- a/stubs/breeze/livewire/resources/views/livewire/profile/connected-accounts-form.blade.php +++ b/stubs/breeze/livewire/resources/views/livewire/profile/connected-accounts-form.blade.php @@ -1,6 +1,5 @@ validate(); - Auth::user()->connectedAccounts() + auth()->user()->connectedAccounts() ->where('id', $id) ->delete(); diff --git a/stubs/breeze/livewire/resources/views/livewire/profile/set-password-form.blade.php b/stubs/breeze/livewire/resources/views/livewire/profile/set-password-form.blade.php index b0711677..6b92556b 100644 --- a/stubs/breeze/livewire/resources/views/livewire/profile/set-password-form.blade.php +++ b/stubs/breeze/livewire/resources/views/livewire/profile/set-password-form.blade.php @@ -17,7 +17,7 @@ public function setPassword(): void 'password' => ['required', 'string', Password::defaults(), 'confirmed'], ]); } catch (ValidationException $e) { - $this->reset('password', 'password_confirmation'); + $this->reset('current_password', 'password', 'password_confirmation'); throw $e; } diff --git a/tests/Unit/InstallerManagerTest.php b/tests/Unit/InstallerManagerTest.php index 81a01c05..32008fba 100644 --- a/tests/Unit/InstallerManagerTest.php +++ b/tests/Unit/InstallerManagerTest.php @@ -3,6 +3,7 @@ namespace JoelButcher\Socialstream\Tests\Unit; use JoelButcher\Socialstream\Installer\Drivers\Breeze\BladeDriver; +use JoelButcher\Socialstream\Installer\Drivers\Breeze\FunctionalLivewireDriver as BreezeLivewireFunctionalDriver; use JoelButcher\Socialstream\Installer\Drivers\Breeze\LivewireDriver as BreezeLivewireDriver; use JoelButcher\Socialstream\Installer\Drivers\Breeze\ReactInertiaDriver; use JoelButcher\Socialstream\Installer\Drivers\Breeze\VueInertiaDriver; @@ -31,6 +32,11 @@ ->toBeInstanceOf(BreezeLivewireDriver::class); }); +it('resolves the functional livewire driver for Laravel Breeze', function () { + expect(app(InstallManager::class)->driver('breeze-livewire-functional')) + ->toBeInstanceOf(BreezeLivewireFunctionalDriver::class); +}); + it('resolves the react driver for Laravel Breeze', function () { expect(app(InstallManager::class)->driver('breeze-react')) ->toBeInstanceOf(ReactInertiaDriver::class);