Skip to content

Commit 69b7f96

Browse files
authored
4 add inertia usage to readme (#5)
1 parent b1be7f1 commit 69b7f96

File tree

5 files changed

+109
-17
lines changed

5 files changed

+109
-17
lines changed

README.md

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,15 @@ return [
157157
After installing Laravel Breeze or your preferred UI scaffolding, you'll need to replace the login form's login step. Instead of authenticating directly, send the OTP email and redirect the user to the OTP entry page.
158158

159159
### Laravel Breeze Livewire Example
160-
1. Replace the [LoginForm authenticate method](https://github.com/laravel/breeze/blob/2.x/stubs/livewire-common/app/Livewire/Forms/LoginForm.php#L29C6-L29C41) with a sendEmail method that runs the SendOtp action. For example:
160+
1. Replace the [LoginForm authenticate method](https://github.com/laravel/breeze/blob/2.x/stubs/livewire-common/app/Livewire/Forms/LoginForm.php#L29C6-L29C41) with a sendEmail method that runs the SendOtp action and returns the newly created Otp.
161+
161162
```php
162-
public function sendEmail(): void
163+
use BenBjurstrom\Otpz\Actions\SendOtp;
164+
use BenBjurstrom\Otpz\Exceptions\OtpThrottleException;
165+
use BenBjurstrom\Otpz\Models\Otp;
166+
//...
167+
168+
public function sendEmail(): Otp
163169
{
164170
$this->validate();
165171

@@ -178,8 +184,7 @@ After installing Laravel Breeze or your preferred UI scaffolding, you'll need to
178184
}
179185
````
180186

181-
2. Next replace [Login component's login method](https://github.com/laravel/breeze/blob/e05ae1a21954c8d83bb0fcc78db87f157c16ac6c/stubs/livewire/resources/views/livewire/pages/auth/login.blade.php#L19-L23) with a method that calls the sendEmail method and redirects to the OTP entry page. For example:
182-
187+
2. Update the [Login component's login method](https://github.com/laravel/breeze/blob/e05ae1a21954c8d83bb0fcc78db87f157c16ac6c/stubs/livewire/resources/views/livewire/pages/auth/login.blade.php#L19-L23) to call the sendEmail method and redirect to the OTP entry page.
183188
```php
184189
public function login(): void
185190
{
@@ -189,6 +194,53 @@ After installing Laravel Breeze or your preferred UI scaffolding, you'll need to
189194
}
190195
```
191196

197+
### Laravel Breeze Inertia Example
198+
199+
1. Remove password from the rules array and replace the [LoginRequest authenticate method](https://github.com/laravel/breeze/blob/e05ae1a21954c8d83bb0fcc78db87f157c16ac6c/stubs/default/app/Http/Requests/Auth/LoginRequest.php#L40) with a sendEmail method that runs the SendOtp action and returns the newly created Otp.
200+
```php
201+
use BenBjurstrom\Otpz\Actions\SendOtp;
202+
use BenBjurstrom\Otpz\Exceptions\OtpThrottleException;
203+
use BenBjurstrom\Otpz\Models\Otp;
204+
//...
205+
206+
public function rules(): array
207+
{
208+
return [
209+
'email' => ['required', 'string', 'email']
210+
];
211+
}
212+
//...
213+
214+
public function sendEmail(): Otp
215+
{
216+
$this->ensureIsNotRateLimited();
217+
RateLimiter::hit($this->throttleKey(), 300);
218+
219+
try {
220+
$otp = (new SendOtp)->handle($this->email);
221+
} catch (OtpThrottleException $e) {
222+
throw ValidationException::withMessages([
223+
'email' => $e->getMessage(),
224+
]);
225+
}
226+
227+
RateLimiter::clear($this->throttleKey());
228+
229+
return $otp;
230+
}
231+
```
232+
233+
2. Update the [AuthenticatedSessionController store method](https://github.com/laravel/breeze/blob/e05ae1a21954c8d83bb0fcc78db87f157c16ac6c/stubs/inertia-common/app/Http/Controllers/Auth/AuthenticatedSessionController.php#L30) to call the sendEmail method and redirect to the OTP entry page.
234+
235+
```php
236+
public function store(LoginRequest $request): \Symfony\Component\HttpFoundation\Response
237+
{
238+
$otp = $request->sendEmail();
239+
240+
return Inertia::location($otp->url);
241+
}
242+
```
243+
192244
Everything else is handled by the package components.
193245

194246
## Testing

resources/views/otp.blade.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,16 @@ class="block w-72 rounded-xl border-zinc-300 p-4 text-center text-2xl uppercase
5959
/>
6060
<input type="hidden" name="email" value="{{$email}}">
6161
</div>
62-
<x-input-error
63-
:messages="$errors->get('code')"
64-
class="mt-2"
65-
id="otp-error"
66-
/>
62+
@if ($errors->get('code'))
63+
<ul
64+
id="otp-error"
65+
class="mt-2 text-sm text-red-600 dark:text-red-400 space-y-1"
66+
>
67+
@foreach ((array) $errors->get('code') as $message)
68+
<li>{{ $message }}</li>
69+
@endforeach
70+
</ul>
71+
@endif
6772
</div>
6873

6974
<div>

src/Http/Controllers/PostOtpController.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,20 @@
44

55
use BenBjurstrom\Otpz\Actions\AttemptOtp;
66
use BenBjurstrom\Otpz\Exceptions\OtpAttemptException;
7+
use BenBjurstrom\Otpz\Http\Requests\OtpRequest;
78
use Illuminate\Http\RedirectResponse;
8-
use Illuminate\Http\Request;
99
use Illuminate\Support\Facades\Auth;
1010
use Illuminate\Support\Facades\Session;
1111
use Illuminate\Validation\ValidationException;
1212
use Illuminate\View\View;
1313

1414
class PostOtpController
1515
{
16-
public function __invoke(Request $request, int $id): RedirectResponse|View
16+
public function __invoke(OtpRequest $request, int $id): RedirectResponse|View
1717
{
18-
$data = $request->validate([
19-
'code' => ['required', 'string', 'size:9'],
20-
]);
21-
2218
try {
19+
$data = $request->safe()->only(['code']);
20+
2321
$otp = (new AttemptOtp)->handle($id, $data['code']);
2422

2523
Auth::loginUsingId($otp->user_id); // fires Illuminate\Auth\Events\Login;

src/Http/Requests/OtpRequest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace BenBjurstrom\Otpz\Http\Requests;
4+
5+
use Illuminate\Contracts\Validation\ValidationRule;
6+
use Illuminate\Foundation\Http\FormRequest;
7+
8+
class OtpRequest extends FormRequest
9+
{
10+
/**
11+
* Determine if the user is authorized to make this request.
12+
*/
13+
public function authorize(): bool
14+
{
15+
return true;
16+
}
17+
18+
/**
19+
* Get the validation rules that apply to the request.
20+
*
21+
* @return array<string, ValidationRule|array|string>
22+
*/
23+
public function rules(): array
24+
{
25+
return [
26+
'code' => ['required', 'string', 'size:9'],
27+
];
28+
}
29+
30+
protected function prepareForValidation(): void
31+
{
32+
$code = preg_replace('/[^0-9A-Z]/', '', strtoupper($this->code));
33+
$this->merge([
34+
'code' => $code,
35+
]);
36+
}
37+
}

src/Models/Otp.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ public function user(): BelongsTo
5858
return $this->belongsTo($authenticatableModel);
5959
}
6060

61-
public function getUrlAttribute()
61+
public function getUrlAttribute(): string
6262
{
63-
URL::temporarySignedRoute('otp.show', now()->addMinutes(5), [
63+
return URL::temporarySignedRoute('otp.show', now()->addMinutes(5), [
6464
'id' => $this->id,
6565
'session' => request()->session()->getId(),
6666
]);

0 commit comments

Comments
 (0)