Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 110
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
AuthController
0.00% covered (danger)
0.00%
0 / 110
0.00% covered (danger)
0.00%
0 / 7
210
0.00% covered (danger)
0.00%
0 / 1
 register
0.00% covered (danger)
0.00%
0 / 32
0.00% covered (danger)
0.00%
0 / 1
6
 login
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
12
 profile
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 logout
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 forgotPassword
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 resetPassword
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
6
 logoutByRole
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace App\Http\Controllers\Api\v1;
4
5use App\Responses\ApiResponse;
6use App\Http\Controllers\Controller;
7use App\Models\User;
8use Illuminate\Http\JsonResponse;
9use Illuminate\Http\Request;
10use Illuminate\Support\Facades\Auth;
11use Illuminate\Support\Facades\Hash;
12use Illuminate\Support\Facades\Password;
13use Illuminate\Support\Facades\Validator;
14use Illuminate\Support\Str;
15
16
17/**
18 * API Version 1 - AuthController
19 */
20class AuthController extends Controller
21{
22    /**
23     * Register a User
24     *
25     * Provide registration capability to the client app
26     *
27     * Registration requires:
28     * - name
29     * - valid email address
30     * - password (min 6 character)
31     *
32     * @param Request $request
33     * @return JsonResponse
34     * @throws \Illuminate\Validation\ValidationException
35     */
36    public function register(Request $request): JsonResponse
37    {
38        //  check https://laravel.com/docs/12.x/validation#rule-email
39        $validator = Validator::make(
40            $request->all(),
41            [
42                'name' => ['required', 'string', 'max:255'],
43                'email' => ['required', 'string', 'email', 'max:255', 'unique:users',],
44                'password' => ['required', 'string', 'min:6', 'confirmed',],
45                'password_confirmation' => ['required', 'string', 'min:6',],
46            ]
47        );
48
49        if ($validator->fails()) {
50            return ApiResponse::error(
51                ['error' => $validator->errors()],
52                'Registration details error',
53                422
54            );
55        }
56
57        $user = User::create([
58            'name' => $validator->validated()['name'],
59            'email' => $validator->validated()['email'],
60            'password' => Hash::make(
61                $validator->validated()['password']
62            ),
63        ]);
64
65        // Assign default 'client' role
66        $user->assignRole('client');
67
68        $token = $user->createToken('MyAppToken')->plainTextToken;
69
70        return ApiResponse::success(
71            [
72                'token' => $token,
73                'user' => $user,
74            ],
75            'User successfully created',
76            201
77        );
78    }
79
80    /**
81     * User Login
82     *
83     * Attempt to log the user in using email
84     * and password based authentication.
85     *
86     * @param Request $request
87     * @return JsonResponse
88     */
89    public function login(Request $request): JsonResponse
90    {
91        
92        $validator = Validator::make($request->all(), [
93            'email' => ['required', 'string', 'email', 'max:255',],
94            'password' => ['required', 'string',],
95        ]);
96
97        if ($validator->fails()) {
98            return ApiResponse::error(
99                [
100                    'error' => $validator->errors()
101                ],
102                'Invalid credentials',
103                401
104            );
105        }
106
107        if (!Auth::attempt($request->only('email', 'password'))) {
108            return ApiResponse::error(
109                [],
110                'Invalid credentials',
111                401);
112        }
113
114        $user = Auth::user();
115        $token = $user->createToken('MyAppToken')->plainTextToken;
116
117        return ApiResponse::success(
118            [
119                'token' => $token,
120                'user' => $user,
121            ],
122            'Login successful'
123        );
124    }
125
126    /**
127     * User Profile API
128     *
129     * Provide the user's profile information, including:
130     * - name,
131     * - email,
132     * - email verified,
133     * - created at, and
134     * - updated at.
135     *
136     * @param Request $request
137     * @return JsonResponse
138     */
139    public function profile(Request $request): JsonResponse
140    {
141        return ApiResponse::success(
142            [
143                'user' => $request->user(),
144            ],
145            'User profile request successful'
146        );
147    }
148
149    /**
150     * User Logout
151     *
152     * Log user out of system, cleaning token and session details.
153     *
154     * @param Request $request
155     * @return JsonResponse
156     */
157    public function logout(Request $request): JsonResponse
158    {
159        $request->user()->tokens()->delete();
160
161        return ApiResponse::success(
162            [],
163            'Logout successful'
164        );
165    }
166
167    /**
168     * Send password reset link to the user's email.
169     */
170    public function forgotPassword(Request $request): JsonResponse
171    {
172        $request->validate([
173            'email' => ['required', 'email'],
174        ]);
175
176        $status = Password::sendResetLink(
177            $request->only('email')
178        );
179
180        if ($status === Password::RESET_LINK_SENT) {
181            return ApiResponse::success(null, __($status));
182        }
183
184        return ApiResponse::error(['email' => __($status)], 'Unable to send reset link', 422);
185    }
186
187    /**
188     * Reset the user's password using a token.
189     */
190    public function resetPassword(Request $request): JsonResponse
191    {
192        $request->validate([
193            'token' => ['required'],
194            'email' => ['required', 'email'],
195            'password' => ['required', 'confirmed', 'min:6'],
196        ]);
197
198        $status = Password::reset(
199            $request->only('email', 'password', 'password_confirmation', 'token'),
200            function ($user) use ($request) {
201                $user->forceFill([
202                    'password' => Hash::make($request->string('password')),
203                    'remember_token' => Str::random(60),
204                ])->save();
205
206                // Revoke all existing tokens on reset
207                $user->tokens()->delete();
208            }
209        );
210
211        if ($status === Password::PASSWORD_RESET) {
212            return ApiResponse::success(null, __($status));
213        }
214
215        return ApiResponse::error(['email' => __($status)], 'Password reset failed', 422);
216    }
217
218    /**
219     * Logout all users holding the specified role.
220     */
221    public function logoutByRole(Request $request, string $role): JsonResponse
222    {
223        try {
224            $users = User::role($role)->get();
225        } catch (\Spatie\Permission\Exceptions\RoleDoesNotExist $e) {
226            return ApiResponse::success(
227                ['revoked_tokens' => 0, 'role' => $role, 'users_affected' => 0],
228                'Logout by role completed - role not found'
229            );
230        }
231
232        $count = 0;
233        foreach ($users as $user) {
234            $deleted = $user->tokens()->delete();
235            $count += $deleted;
236        }
237
238        return ApiResponse::success(
239            ['revoked_tokens' => $count, 'role' => $role, 'users_affected' => $users->count()],
240            'Logout by role completed'
241        );
242    }
243
244}