Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.24% covered (success)
95.24%
40 / 42
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
Auth
95.24% covered (success)
95.24%
40 / 42
50.00% covered (danger)
50.00%
1 / 2
8
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 login
95.12% covered (success)
95.12%
39 / 41
0.00% covered (danger)
0.00%
0 / 1
7
1<?php
2
3namespace App\Http\Controllers;
4
5use App\Services\AuthService;
6use Illuminate\Http\JsonResponse;
7use Illuminate\Http\Request;
8use Illuminate\Support\Facades\Http;
9use Illuminate\Support\Facades\Log;
10
11class Auth extends Controller
12{
13    private $authService;
14
15    /**
16     * HTTP status codes and their corresponding error messages.
17     *
18     * @var array<int, string>
19     */
20    private $statusError = [
21        404 => 'Page not found',
22        401 => 'Unauthorized',
23        500 => 'Internal Server Error',
24        502 => 'Bad Gateway',
25    ];
26
27    public function __construct(AuthService $authService)
28    {
29        $this->authService = $authService;
30    }
31
32    /**
33     * Authenticate a user and return an API token.
34     *
35     * @param  Request  $request  Expected keys: 'email' (string), 'password' (string)
36     * @return JsonResponse
37     *
38     * @response {
39     *   "token": "string",
40     *   "token_expires_at": "datetime",
41     *   "token_type": "Bearer"
42     * }
43     */
44    public function login(Request $request)
45    {
46        try {
47            if (empty($request->all())) {
48                throw new \Exception('Request parameters not set', 404);
49            }
50
51            $request->validate([
52                'email' => 'required|string|email',
53                'password' => 'required|string',
54            ]);
55
56            $token = null;
57
58            if ($request->header('X-Auth-Token') && $request->header('X-Request-Source') == 'external_app') {
59                $token = $this->authService->validateCrossAppToken($request->header('X-Auth-Token'));
60            }
61
62            $tokenData = $this->authService->login(
63                $request->input('email'),
64                $request->input('password'),
65                $token
66            );
67
68            if (! $token) {
69                $crossAppToken = $this->authService->generateCrossAppToken($tokenData['api_token']);
70
71                $response = Http::withHeaders([
72                    'X-Auth-Token' => $crossAppToken,
73                    'X-Request-Source' => 'external_app',
74                ])->asForm()->post('https://crm.fireservicetitan.com:8081/api/login', [
75                    'email' => $request->input('email'),
76                    'password' => $request->input('password'),
77                ]);
78
79                /*if (!in_array($response->status(), $this->statusException, true)) {
80                    throw new \Exception('Connection Auth failed', 502);
81                }*/
82                Log::channel('third-party')->warning('Not token generated in crm for '.$request->input('email'));
83            }
84
85            return response()->json([
86                'token' => $tokenData['api_token'],
87                'token_expires_at' => $tokenData['token_expires_at'],
88                'token_type' => 'Bearer',
89            ]);
90
91        } catch (\Exception $e) {
92            /** @disregard P1014 */
93            $e->exceptionCode = 'AUTH_EXCEPTION';
94            report($e);
95            $code = $e->exceptionCode ?: 500;
96
97            Log::channel('third-party')->error("Auth error: {$e->getMessage()}", [
98                'code' => $code,
99                'email' => $request->input('email'),
100            ]);
101
102            return response()->json(
103                ['error' => $this->statusError[$code]],
104                $code
105            );
106        }
107    }
108}