LoginController::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 5
rs 10
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use App\Constants\TranslationCode;
6
use App\Models\User;
7
use App\Models\UserToken;
8
use App\Services\LogService;
9
use App\Services\UserService;
10
use Illuminate\Http\JsonResponse;
11
use Illuminate\Http\Request;
12
use Illuminate\Support\Facades\Auth;
13
use Illuminate\Support\Facades\DB;
14
use Illuminate\Support\Facades\Log;
15
use Laravel\Socialite\Facades\Socialite;
16
use Throwable;
17
18
/**
19
 * Class LoginController
20
 *
21
 * @package App\Http\Controllers
22
 */
23
class LoginController extends Controller
24
{
25
    /** @var UserService */
26
    private $userService;
27
28
    /**
29
     * UserController constructor.
30
     */
31
    public function __construct()
32
    {
33
        parent::__construct();
34
35
        $this->userService = new UserService();
36
    }
37
38
    /**
39
     * Login user with email and password or remember token
40
     *
41
     * @param  Request  $request
42
     *
43
     * @return JsonResponse
44
     */
45
    public function login(Request $request)
46
    {
47
        try {
48
            $validator = $this->userService->validateLoginRequest($request);
49
50
            if (!$validator->passes()) {
51
                return $this->userErrorResponse($validator->messages()->toArray());
52
            }
53
54
            $user = $this->userService->loginUser($request->only('email', 'password'));
55
56
            if (!$user) {
57
                return $this->userErrorResponse(['credentials' => TranslationCode::ERROR_CREDENTIALS_INVALID]);
58
            }
59
60
            if ($user->status === User::STATUS_UNCONFIRMED) {
61
                return $this->userErrorResponse(['account' => TranslationCode::ERROR_ACCOUNT_UNACTIVATED]);
62
            }
63
64
            $loginData = $this->userService->generateLoginData($user, $request->has('remember'));
65
66
            return $this->successResponse($loginData);
67
        } catch (Throwable $t) {
68
            Log::error(LogService::getThrowableTraceAsString($t, $request));
69
70
            return $this->errorResponse();
71
        }
72
    }
73
74
    /**
75
     * Login with remember token
76
     *
77
     * @param  Request  $request
78
     *
79
     * @return JsonResponse
80
     */
81
    public function loginWithRememberToken(Request $request)
82
    {
83
        try {
84
            $validator = $this->userService->validateTokenLoginRequest($request);
85
86
            if (!$validator->passes()) {
87
                return $this->userErrorResponse($validator->messages()->toArray());
88
            }
89
90
            $rememberToken = $request->get('rememberToken');
91
92
            $user = $this->userService->loginUserWithRememberToken($rememberToken);
93
94
            if (!$user) {
0 ignored issues
show
introduced by
$user is of type App\Models\User, thus it always evaluated to true.
Loading history...
95
                return $this->userErrorResponse(['rememberToken' => TranslationCode::ERROR_REMEMBER_TOKEN_INVALID]);
96
            }
97
98
            if ($user->status === User::STATUS_UNCONFIRMED) {
99
                return $this->userErrorResponse(['account' => TranslationCode::ERROR_ACCOUNT_UNACTIVATED]);
100
            }
101
102
            DB::beginTransaction();
103
104
            $this->userService->updateRememberTokenValability($rememberToken);
105
106
            $loginData = $this->userService->generateLoginData($user);
107
108
            DB::commit();
109
110
            return $this->successResponse($loginData);
111
        } catch (Throwable $t) {
112
            Log::error(LogService::getThrowableTraceAsString($t, $request));
113
114
            return $this->errorResponse();
115
        }
116
    }
117
118
    /**
119
     * Login with facebook
120
     *
121
     * @param  Request  $request
122
     *
123
     * @return JsonResponse
124
     */
125
    public function loginWithFacebook(Request $request)
126
    {
127
        try {
128
            $validator = $this->userService->validateFacebookLoginRequest($request);
129
130
            if (!$validator->passes()) {
131
                return $this->userErrorResponse($validator->messages()->toArray());
132
            }
133
134
            $token = $request->get('accessToken');
135
136
            try {
137
                $facebookUser = Socialite::driver('facebook')->userFromToken($token);
0 ignored issues
show
Bug introduced by
The method userFromToken() does not exist on Laravel\Socialite\Contracts\Provider. It seems like you code against a sub-type of Laravel\Socialite\Contracts\Provider such as Laravel\Socialite\Two\AbstractProvider. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

137
                $facebookUser = Socialite::driver('facebook')->/** @scrutinizer ignore-call */ userFromToken($token);
Loading history...
138
            } catch (Throwable $t) {
139
                return $this->userErrorResponse(['token' => TranslationCode::ERROR_FACEBOOK_ACCESS_TOKEN_INVALID]);
140
            }
141
142
            if ($facebookUser->getId() !== $request->get('facebookId')) {
143
                return $this->userErrorResponse(['token' => TranslationCode::ERROR_FACEBOOK_ACCESS_TOKEN_MISMATCH]);
144
            }
145
146
            if (!$facebookUser->getEmail()) {
147
                return $this->userErrorResponse(['permission' => TranslationCode::ERROR_FACEBOOK_PERMISSION_EMAIL]);
148
            }
149
150
            DB::beginTransaction();
151
152
            $user = $this->userService->loginUserWithSocial($facebookUser, $this->baseService->getLanguage($request),
153
                'facebook_id');
154
155
            $loginData = $this->userService->generateLoginData($user);
156
157
            DB::commit();
158
159
            return $this->successResponse($loginData);
160
        } catch (Throwable $t) {
161
            Log::error(LogService::getThrowableTraceAsString($t, $request));
162
163
            return $this->errorResponse();
164
        }
165
    }
166
167
    /**
168
     * Login with google
169
     *
170
     * @param  Request  $request
171
     *
172
     * @return JsonResponse
173
     */
174
    public function loginWithGoogle(Request $request)
175
    {
176
        try {
177
            $validator = $this->userService->validateGoogleLoginRequest($request);
178
179
            if (!$validator->passes()) {
180
                return $this->userErrorResponse($validator->messages()->toArray());
181
            }
182
183
            $token = $request->get('accessToken');
184
185
            try {
186
                $googleUser = Socialite::driver('google')->userFromToken($token);
187
            } catch (Throwable $t) {
188
                return $this->userErrorResponse(['token' => TranslationCode::ERROR_GOOGLE_ACCESS_TOKEN_INVALID]);
189
            }
190
191
            if ($googleUser->getId() !== $request->get('google_id')) {
192
                return $this->userErrorResponse(['token' => TranslationCode::ERROR_GOOGLE_ACCESS_TOKEN_MISMATCH]);
193
            }
194
195
            if (!$googleUser->getEmail()) {
196
                return $this->userErrorResponse(['permission' => TranslationCode::ERROR_GOOGLE_PERMISSION_EMAIL]);
197
            }
198
199
            DB::beginTransaction();
200
201
            $user = $this->userService->loginUserWithSocial($googleUser, $this->baseService->getLanguage($request),
202
                'google_id');
203
204
            $loginData = $this->userService->generateLoginData($user);
205
206
            DB::commit();
207
208
            return $this->successResponse($loginData);
209
        } catch (Throwable $t) {
210
            Log::error(LogService::getThrowableTraceAsString($t, $request));
211
212
            return $this->errorResponse();
213
        }
214
    }
215
216
    /**
217
     * Logout user
218
     *
219
     * @param  Request  $request
220
     *
221
     * @return JsonResponse
222
     */
223
    public function logout(Request $request)
224
    {
225
        try {
226
            /** @var User $user */
227
            $user = Auth::user();
228
229
            if ($request->has('rememberToken') || $request->has('everywhere')) {
230
                DB::beginTransaction();
231
232
                $userTokens = UserToken::where('user_id', $user->id)
233
                                       ->where('type', UserToken::TYPE_REMEMBER_ME);
234
235
                if ($request->has('rememberToken')) {
236
                    $userTokens = $userTokens->where('token', $request->get('rememberToken'));
237
                }
238
239
                $userTokens->delete();
240
241
                DB::commit();
242
            }
243
244
            return $this->successResponse();
245
        } catch (Throwable $t) {
246
            Log::error(LogService::getThrowableTraceAsString($t, $request));
247
248
            return $this->errorResponse();
249
        }
250
    }
251
}
252