Skip to content

Commit a30120a

Browse files
committed
User Auth - part 34
1 parent 9bfac7d commit a30120a

17 files changed

+835
-24
lines changed

app/Actions/Fortify/CreateNewUser.php

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace App\Actions\Fortify;
4+
5+
use App\Models\User;
6+
use Illuminate\Support\Facades\Hash;
7+
use Illuminate\Support\Facades\Validator;
8+
use Illuminate\Validation\Rule;
9+
use Laravel\Fortify\Contracts\CreatesNewUsers;
10+
11+
class CreateNewUser implements CreatesNewUsers
12+
{
13+
use PasswordValidationRules;
14+
15+
/**
16+
* Validate and create a newly registered user.
17+
*
18+
* @param array<string, string> $input
19+
*/
20+
public function create(array $input): User
21+
{
22+
Validator::make($input, [
23+
'name' => ['required', 'string', 'max:255'],
24+
'email' => [
25+
'required',
26+
'string',
27+
'email',
28+
'max:255',
29+
Rule::unique(User::class),
30+
],
31+
'password' => $this->passwordRules(),
32+
])->validate();
33+
34+
return User::create([
35+
'name' => $input['name'],
36+
'email' => $input['email'],
37+
'password' => Hash::make($input['password']),
38+
]);
39+
}
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace App\Actions\Fortify;
4+
5+
use Laravel\Fortify\Rules\Password;
6+
7+
trait PasswordValidationRules
8+
{
9+
/**
10+
* Get the validation rules used to validate passwords.
11+
*
12+
* @return array<int, \Illuminate\Contracts\Validation\Rule|array|string>
13+
*/
14+
protected function passwordRules(): array
15+
{
16+
return ['required', 'string', new Password, 'confirmed'];
17+
}
18+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace App\Actions\Fortify;
4+
5+
use App\Models\User;
6+
use Illuminate\Support\Facades\Hash;
7+
use Illuminate\Support\Facades\Validator;
8+
use Laravel\Fortify\Contracts\ResetsUserPasswords;
9+
10+
class ResetUserPassword implements ResetsUserPasswords
11+
{
12+
use PasswordValidationRules;
13+
14+
/**
15+
* Validate and reset the user's forgotten password.
16+
*
17+
* @param array<string, string> $input
18+
*/
19+
public function reset(User $user, array $input): void
20+
{
21+
Validator::make($input, [
22+
'password' => $this->passwordRules(),
23+
])->validate();
24+
25+
$user->forceFill([
26+
'password' => Hash::make($input['password']),
27+
])->save();
28+
}
29+
}
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace App\Actions\Fortify;
4+
5+
use App\Models\User;
6+
use Illuminate\Support\Facades\Hash;
7+
use Illuminate\Support\Facades\Validator;
8+
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
9+
10+
class UpdateUserPassword implements UpdatesUserPasswords
11+
{
12+
use PasswordValidationRules;
13+
14+
/**
15+
* Validate and update the user's password.
16+
*
17+
* @param array<string, string> $input
18+
*/
19+
public function update(User $user, array $input): void
20+
{
21+
Validator::make($input, [
22+
'current_password' => ['required', 'string', 'current_password:web'],
23+
'password' => $this->passwordRules(),
24+
], [
25+
'current_password.current_password' => __('The provided password does not match your current password.'),
26+
])->validateWithBag('updatePassword');
27+
28+
$user->forceFill([
29+
'password' => Hash::make($input['password']),
30+
])->save();
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace App\Actions\Fortify;
4+
5+
use App\Models\User;
6+
use Illuminate\Contracts\Auth\MustVerifyEmail;
7+
use Illuminate\Support\Facades\Validator;
8+
use Illuminate\Validation\Rule;
9+
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;
10+
11+
class UpdateUserProfileInformation implements UpdatesUserProfileInformation
12+
{
13+
/**
14+
* Validate and update the given user's profile information.
15+
*
16+
* @param array<string, string> $input
17+
*/
18+
public function update(User $user, array $input): void
19+
{
20+
Validator::make($input, [
21+
'name' => ['required', 'string', 'max:255'],
22+
23+
'email' => [
24+
'required',
25+
'string',
26+
'email',
27+
'max:255',
28+
Rule::unique('users')->ignore($user->id),
29+
],
30+
])->validateWithBag('updateProfileInformation');
31+
32+
if ($input['email'] !== $user->email &&
33+
$user instanceof MustVerifyEmail) {
34+
$this->updateVerifiedUser($user, $input);
35+
} else {
36+
$user->forceFill([
37+
'name' => $input['name'],
38+
'email' => $input['email'],
39+
])->save();
40+
}
41+
}
42+
43+
/**
44+
* Update the given verified user's profile information.
45+
*
46+
* @param array<string, string> $input
47+
*/
48+
protected function updateVerifiedUser(User $user, array $input): void
49+
{
50+
$user->forceFill([
51+
'name' => $input['name'],
52+
'email' => $input['email'],
53+
'email_verified_at' => null,
54+
])->save();
55+
56+
$user->sendEmailVerificationNotification();
57+
}
58+
}
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace App\Providers;
4+
5+
use App\Actions\Fortify\CreateNewUser;
6+
use App\Actions\Fortify\ResetUserPassword;
7+
use App\Actions\Fortify\UpdateUserPassword;
8+
use App\Actions\Fortify\UpdateUserProfileInformation;
9+
use Illuminate\Cache\RateLimiting\Limit;
10+
use Illuminate\Http\Request;
11+
use Illuminate\Support\Facades\RateLimiter;
12+
use Illuminate\Support\ServiceProvider;
13+
use Illuminate\Support\Str;
14+
use Laravel\Fortify\Fortify;
15+
16+
class FortifyServiceProvider extends ServiceProvider
17+
{
18+
/**
19+
* Register any application services.
20+
*/
21+
public function register(): void
22+
{
23+
//
24+
}
25+
26+
/**
27+
* Bootstrap any application services.
28+
*/
29+
public function boot(): void
30+
{
31+
Fortify::loginView(function () {
32+
return view('auth.login');
33+
});
34+
Fortify::createUsersUsing(CreateNewUser::class);
35+
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
36+
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
37+
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
38+
39+
RateLimiter::for('login', function (Request $request) {
40+
$throttleKey = Str::transliterate(Str::lower($request->input(Fortify::username())).'|'.$request->ip());
41+
42+
return Limit::perMinute(5)->by($throttleKey);
43+
});
44+
45+
RateLimiter::for('two-factor', function (Request $request) {
46+
return Limit::perMinute(5)->by($request->session()->get('login.id'));
47+
});
48+
}
49+
}

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"require": {
88
"php": "^8.1",
99
"guzzlehttp/guzzle": "^7.2",
10+
"laravel/fortify": "^1.17",
1011
"laravel/framework": "^10.10",
1112
"laravel/sanctum": "^3.2",
1213
"laravel/tinker": "^2.8"

0 commit comments

Comments
 (0)