Skip to content

Commit 287bad0

Browse files
committed
feat: improve user authentication classes and response handling
1 parent 3c40f65 commit 287bad0

File tree

8 files changed

+188
-43
lines changed

8 files changed

+188
-43
lines changed

Traits/HttpResponseException.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Danilowa\LaravelApiAuth\Traits;
4+
5+
use Danilowa\LaravelResponseBuilder\JsonResponse;
6+
use Illuminate\Http\Exceptions\HttpResponseException as IlluminateHttpResponseException;
7+
use Illuminate\Contracts\Validation\Validator;
8+
9+
/**
10+
* --------------------------------------------------------------------------
11+
* HTTP Response Exception Trait
12+
* --------------------------------------------------------------------------
13+
*
14+
* This trait provides a method to handle validation exceptions by throwing
15+
* an HttpResponseException with a structured JSON response containing the
16+
* validation errors.
17+
*/
18+
trait HttpResponseException
19+
{
20+
/**
21+
* Handle a failed validation attempt and throw an HttpResponseException.
22+
*
23+
* This method constructs a JSON error response using the validation errors
24+
* and throws an IlluminateHttpResponseException with the specified status code.
25+
*
26+
* @param Validator $validator The validator instance containing the validation errors.
27+
* @param int $statusCode The HTTP status code for the response (default is 422).
28+
* @throws IlluminateHttpResponseException
29+
*/
30+
protected function HttpResponseException(Validator $validator, int $statusCode = 422): void
31+
{
32+
throw new IlluminateHttpResponseException(
33+
JsonResponse::error($statusCode, $validator->errors()->all())
34+
);
35+
}
36+
}

composer.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "danilowa/laravel-api-auth",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "A simple and configurable Laravel package for easy API authentication with standardized responses.",
55
"type": "library",
66
"license": "MIT",
@@ -22,8 +22,8 @@
2222
"authors": [
2323
{
2424
"name": "Danilo Oliveira",
25-
"email": "seu-email@example.com",
26-
"homepage": "https://seu-site.com",
25+
"email": "daniloworkdev@gmail.com",
26+
"homepage": "http://www.daniloo.dev",
2727
"role": "Developer"
2828
}
2929
],
@@ -41,7 +41,8 @@
4141
"Danilowa\\LaravelApiAuth\\Routes\\": "src/Routes/",
4242
"Danilowa\\LaravelApiAuth\\DTOs\\": "src/DTOs/",
4343
"Danilowa\\LaravelApiAuth\\Providers\\": "src/Providers/",
44-
"Danilowa\\LaravelApiAuth\\Services\\": "src/Services/"
44+
"Danilowa\\LaravelApiAuth\\Services\\": "src/Services/",
45+
"Danilowa\\LaravelApiAuth\\Traits\\": "src/Traits/"
4546
}
4647
},
4748
"autoload-dev": {
@@ -61,4 +62,4 @@
6162
"optimize-autoloader": true,
6263
"preferred-install": "dist"
6364
}
64-
}
65+
}

config/apiauth.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* The fully qualified class name of the user model that will be used
2323
* for authentication. Update this value if you have a custom user model.
2424
*/
25-
'user_model' => 'App\Models\User::class',
25+
'user_model' => \App\Models\User::class,
2626

2727
/**
2828
* --------------------------------------------------------------------------
@@ -57,10 +57,13 @@
5757
*/
5858
'messages' => [
5959
'user_created' => 'User created successfully!',
60+
'user_not_logged_in' => 'User not logged in.',
6061
'user_logged_in' => 'User logged in!',
6162
'credentials_incorrect' => 'The provided credentials are incorrect.',
6263
'tokens_revoked' => 'Tokens revoked successfully!',
64+
'token_revoked' => 'Token revoked successfully!',
6365
'default_error' => 'An error occurred.',
66+
'no_active_token' => 'No active token found.',
6467
],
6568

6669
/**
@@ -79,6 +82,13 @@
7982
// You can add or remove custom rules as needed here
8083
],
8184
],
85+
'logout' => [
86+
'rules' => [
87+
'email' => 'required|email',
88+
'password' => 'required|string',
89+
// You can add or remove custom rules as needed here
90+
],
91+
],
8292
'registration' => [
8393
'rules' => [
8494
'name' => 'required|string|max:255',

src/Controllers/AuthenticationController.php

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
namespace Danilowa\LaravelApiAuth\Controllers;
44

5-
use Illuminate\Http\Request;
65
use Illuminate\Http\JsonResponse;
76
use Illuminate\Routing\Controller;
87
use Illuminate\Support\Facades\Auth;
98
use Illuminate\Support\Facades\Hash;
109
use Danilowa\LaravelApiAuth\DTOs\UserLoginData;
10+
use Danilowa\LaravelApiAuth\DTOs\UserLogoutData;
1111
use Danilowa\LaravelApiAuth\DTOs\UserRegistrationData;
1212
use Danilowa\LaravelApiAuth\Services\AccessTokenService;
13+
use Danilowa\LaravelResponseBuilder\JsonResponse as JsonResponseBuilder;
1314

1415
class AuthenticationController extends Controller
1516
{
@@ -29,20 +30,23 @@ public function __construct(AccessTokenService $accessTokenService)
2930
/**
3031
* Register a new user and create an access token.
3132
*
32-
* @param UserRegistrationData $request
33-
* @return JsonResponse
33+
* This method handles the registration of a new user.
34+
* It validates the provided data, creates a new user in the database,
35+
* and generates an access token for the user.
36+
*
37+
* @param UserRegistrationData $request The user registration data transfer object.
38+
* @return JsonResponse A JSON response containing the newly created user and their access token.
3439
*/
3540
public function register(UserRegistrationData $request): JsonResponse
3641
{
37-
$user = $this->userModel::create([
38-
'name' => $request->name,
39-
'email' => $request->email,
40-
'password' => Hash::make($request->password),
41-
]);
42+
$data = $request->only(array_keys(config('apiauth.validation.registration.rules')));
43+
$data['password'] = Hash::make($request->password);
44+
45+
$user = $this->userModel::create($data);
4246

4347
$token = $this->accessTokenService->createToken($user, $request->token_name ?? $this->defaultTokenName);
4448

45-
return JsonResponse::success([
49+
return JsonResponseBuilder::success([
4650
'user' => $user,
4751
'token' => $token->plainTextToken,
4852
], $this->getMessage('user_created'), 201);
@@ -51,19 +55,22 @@ public function register(UserRegistrationData $request): JsonResponse
5155
/**
5256
* Log a user in and create an access token.
5357
*
54-
* @param UserLoginData $request
55-
* @return JsonResponse
58+
* This method attempts to authenticate a user using the provided credentials.
59+
* If successful, it generates an access token for the authenticated user.
60+
*
61+
* @param UserLoginData $request The user login data transfer object.
62+
* @return JsonResponse A JSON response containing the access token and the authenticated user.
5663
*/
5764
public function login(UserLoginData $request): JsonResponse
5865
{
59-
if (!Auth::attempt($request->only('email', 'password'))) {
60-
return JsonResponse::error(401, $this->getMessage('credentials_incorrect'));
66+
if (!Auth::attempt($request->only(array_keys(config('apiauth.validation.login.rules'))))) {
67+
return JsonResponseBuilder::error(401, $this->getMessage('credentials_incorrect'));
6168
}
6269

6370
$user = Auth::user();
6471
$token = $this->accessTokenService->createToken($user, $request->token_name ?? $this->defaultTokenName);
6572

66-
return JsonResponse::success([
73+
return JsonResponseBuilder::success([
6774
'token' => $token->plainTextToken,
6875
'user' => $user,
6976
], $this->getMessage('user_logged_in'));
@@ -72,42 +79,55 @@ public function login(UserLoginData $request): JsonResponse
7279
/**
7380
* Log the user out, revoking their access tokens.
7481
*
75-
* @param Request $request
76-
* @return JsonResponse
82+
* This method allows a user to log out by revoking their access tokens.
83+
* It checks whether the user is authenticated and whether they have any active tokens.
84+
*
85+
* @param UserLogoutData $request The user logout data transfer object.
86+
* @return JsonResponse A JSON response indicating the outcome of the logout process.
7787
*/
78-
public function logout(Request $request): JsonResponse
88+
public function logout(UserLogoutData $request): JsonResponse
7989
{
90+
if (!Auth::attempt($request->only('email', 'password'))) {
91+
return JsonResponseBuilder::error(401, $this->getMessage('credentials_incorrect'));
92+
}
93+
94+
$user = $this->userModel::find($request->user()->id);
8095
$revokeAll = config('apiauth.revoke_all_tokens');
8196

82-
if ($revokeAll) {
83-
$request->user()->tokens()->delete();
84-
return JsonResponse::success([], $this->getMessage('tokens_revoked'));
97+
if ($user->tokens()->count() === 0) {
98+
return JsonResponseBuilder::error(404, $this->getMessage('no_active_token'));
8599
}
86100

87-
$token = $request->user()->currentAccessToken();
88-
if (!$token) {
89-
return JsonResponse::error(404, $this->getMessage('no_active_token'));
101+
if ($revokeAll) {
102+
$user->tokens()->delete();
103+
return JsonResponseBuilder::success([], $this->getMessage('tokens_revoked'));
90104
}
91105

106+
$token = $user->tokens()->first();
92107
$this->accessTokenService->revokeToken($token);
93-
return JsonResponse::success([], $this->getMessage('tokens_revoked'));
108+
return JsonResponseBuilder::success([], $this->getMessage('token_revoked'));
94109
}
95110

96111
/**
97112
* Get the currently authenticated user.
98113
*
99-
* @return JsonResponse
114+
* This method retrieves the currently authenticated user's information.
115+
*
116+
* @return JsonResponse A JSON response containing the authenticated user's data.
100117
*/
101118
public function currentUser(): JsonResponse
102119
{
103-
return JsonResponse::success(Auth::user());
120+
return JsonResponseBuilder::success(Auth::user());
104121
}
105122

106123
/**
107124
* Retrieve a message from the configuration.
108125
*
109-
* @param string $key
110-
* @return string
126+
* This private method fetches a message from the configuration based on the provided key.
127+
* If the key does not exist, it returns a default message.
128+
*
129+
* @param string $key The key for the message in the configuration.
130+
* @return string The corresponding message or a default message if not found.
111131
*/
112132
private function getMessage(string $key): string
113133
{

src/DTOs/UserLoginData.php

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,47 @@
22

33
namespace Danilowa\LaravelApiAuth\DTOs;
44

5+
use Illuminate\Contracts\Validation\Validator;
56
use Illuminate\Foundation\Http\FormRequest;
7+
use Danilowa\LaravelApiAuth\Traits\HttpResponseException;
68

79
/**
810
* --------------------------------------------------------------------------
9-
* User Login Data
11+
* User Login Data Transfer Object
1012
* --------------------------------------------------------------------------
1113
*
1214
* This class handles the validation rules for user login requests.
13-
* It extends the FormRequest class to utilize Laravel's validation features.
15+
* It extends the FormRequest class to utilize Laravel's validation features
16+
* and provides a structured way to validate user login data.
1417
*/
1518
class UserLoginData extends FormRequest
1619
{
20+
use HttpResponseException;
21+
1722
/**
1823
* Get the validation rules that apply to the request.
1924
*
25+
* This method retrieves the validation rules defined in the configuration
26+
* for user login, ensuring that the data meets the specified criteria.
27+
*
2028
* @return array The validation rules for user login.
2129
*/
22-
public function rules()
30+
public function rules(): array
2331
{
24-
// Retrieve the validation rules from the configuration
25-
$rules = config('apiauth.validation.login.rules');
32+
return config('apiauth.validation.login.rules');
33+
}
2634

27-
return $rules;
35+
/**
36+
* Handle a failed validation attempt.
37+
*
38+
* This method is triggered when validation fails, providing a custom
39+
* response that includes the validation errors.
40+
*
41+
* @param Validator $validator The validator instance containing the errors.
42+
* @return void
43+
*/
44+
protected function failedValidation(Validator $validator): void
45+
{
46+
$this->HttpResponseException($validator, 422);
2847
}
2948
}

src/DTOs/UserLogoutData.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Danilowa\LaravelApiAuth\DTOs;
4+
5+
use Illuminate\Contracts\Validation\Validator;
6+
use Illuminate\Foundation\Http\FormRequest;
7+
use Danilowa\LaravelApiAuth\Traits\HttpResponseException;
8+
9+
/**
10+
* --------------------------------------------------------------------------
11+
* User Logout Data
12+
* --------------------------------------------------------------------------
13+
*
14+
* This class handles the validation rules for user logout requests.
15+
* It extends the FormRequest class to utilize Laravel's validation features.
16+
*/
17+
class UserLogoutData extends FormRequest
18+
{
19+
use HttpResponseException;
20+
21+
/**
22+
* Get the validation rules that apply to the request.
23+
*
24+
* @return array The validation rules for user logout.
25+
*/
26+
public function rules(): array
27+
{
28+
// Retrieve the validation rules from the configuration
29+
return config('apiauth.validation.logout.rules');
30+
}
31+
32+
/**
33+
* Handle a failed validation attempt.
34+
*
35+
* @param Validator $validator The validator instance containing the validation errors.
36+
* @throws Illuminate\Http\Exceptions\HttpResponseException
37+
*/
38+
protected function failedValidation(Validator $validator): void
39+
{
40+
$this->HttpResponseException($validator, 422);
41+
}
42+
}

src/DTOs/UserRegistrationData.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace Danilowa\LaravelApiAuth\DTOs;
44

5+
use Illuminate\Contracts\Validation\Validator;
56
use Illuminate\Foundation\Http\FormRequest;
7+
use Danilowa\LaravelApiAuth\Traits\HttpResponseException;
68

79
/**
810
* --------------------------------------------------------------------------
@@ -14,16 +16,27 @@
1416
*/
1517
class UserRegistrationData extends FormRequest
1618
{
19+
use HttpResponseException;
20+
1721
/**
1822
* Get the validation rules that apply to the request.
1923
*
2024
* @return array The validation rules for user registration.
2125
*/
22-
public function rules()
26+
public function rules(): array
2327
{
2428
// Retrieve the validation rules from the configuration
25-
$rules = config('apiauth.validation.registration.rules');
29+
return config('apiauth.validation.registration.rules');
30+
}
2631

27-
return $rules;
32+
/**
33+
* Handle a failed validation attempt.
34+
*
35+
* @param Validator $validator The validator instance containing the validation errors.
36+
* @throws Illuminate\Http\Exceptions\HttpResponseException
37+
*/
38+
protected function failedValidation(Validator $validator): void
39+
{
40+
$this->HttpResponseException($validator, 422);
2841
}
2942
}

0 commit comments

Comments
 (0)