Passed
Push — master ( 35ff5f...63edb8 )
by Ion
03:15
created

UserService::validateResendActivationCodeRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 12
rs 10
1
<?php
2
3
namespace App\Services;
4
5
use App\Constants\TranslationCode;
6
use App\Models\Language;
7
use App\Models\User;
8
use App\Models\UserToken;
9
use Carbon\Carbon;
10
use Illuminate\Contracts\Validation\Validator as ReturnedValidator;
11
use Illuminate\Http\Request;
12
use Illuminate\Support\Facades\Auth;
13
use Illuminate\Support\Facades\File;
14
use Illuminate\Support\Facades\Hash;
15
use Illuminate\Support\Facades\Validator;
16
use Illuminate\Support\Str;
17
use IonGhitun\JwtToken\Exceptions\JwtException;
18
use IonGhitun\JwtToken\Jwt;
19
use Laravel\Socialite\Two\User as SocialiteUser;
20
use Symfony\Component\HttpFoundation\File\UploadedFile;
21
22
/**
23
 * Class UserService
24
 *
25
 * TODO
26
 *
27
 * @package App\Services
28
 */
29
class UserService
30
{
31
    /**
32
     * Validate request on login
33
     *
34
     * @param Request $request
35
     *
36
     * @return ReturnedValidator
37
     */
38
    public function validateLoginRequest(Request $request)
39
    {
40
        $rules = [
41
            'email' => 'required|email|exists_encrypted:users,email',
42
            'password' => 'required'
43
        ];
44
45
        $messages = [
46
            'email.required' => TranslationCode::ERROR_EMAIL_REQUIRED,
47
            'email.email' => TranslationCode::ERROR_EMAIL_INVALID,
48
            'email.exists_encrypted' => TranslationCode::ERROR_EMAIL_NOT_REGISTERED,
49
            'password.required' => TranslationCode::ERROR_PASSWORD_REQUIRED
50
        ];
51
52
        return Validator::make($request->all(), $rules, $messages);
53
    }
54
55
    /**
56
     * Validate request on login with remember token
57
     *
58
     * @param Request $request
59
     *
60
     * @return ReturnedValidator
61
     */
62
    public function validateTokenLoginRequest(Request $request)
63
    {
64
        $rules = [
65
            'rememberToken' => 'required'
66
        ];
67
68
        $messages = [
69
            'rememberToken.required' => TranslationCode::ERROR_REMEMBER_TOKEN_REQUIRED
70
        ];
71
72
        return Validator::make($request->all(), $rules, $messages);
73
    }
74
75
    /**
76
     * Get user from email and password
77
     *
78
     * @param array $credentials
79
     *
80
     * @return User|null
81
     */
82
    public function loginUser(array $credentials)
83
    {
84
        /** @var User $user */
85
        $user = User::whereEncrypted('email', $credentials['email'])
86
            ->first();
87
88
        if (!$user) {
0 ignored issues
show
introduced by
$user is of type App\Models\User, thus it always evaluated to true.
Loading history...
89
            return null;
90
        }
91
92
        $password = $user->password;
93
94
        if (app('hash')->check($credentials['password'], $password)) {
95
            return $user;
96
        }
97
98
        return null;
99
    }
100
101
    /**
102
     * Generate returned data on login
103
     *
104
     * @param User $user
105
     * @param bool $remember
106
     *
107
     * @return array
108
     *
109
     * @throws JwtException
110
     */
111
    public function generateLoginData(User $user, $remember = false)
112
    {
113
        $data = [
114
            'user' => $user,
115
            'token' => Jwt::generateToken([
116
                'id' => $user->id
117
            ])
118
        ];
119
120
        if ($remember) {
121
            $data['rememberToken'] = $this->generateRememberMeToken($user->id);
122
        }
123
124
        return $data;
125
    }
126
127
    /**
128
     * Generate remember me token
129
     *
130
     * @param $userId
131
     * @param $days
132
     *
133
     * @return string
134
     */
135
    public function generateRememberMeToken($userId, $days = 14)
136
    {
137
        $userToken = new UserToken();
138
139
        $userToken->user_id = $userId;
140
        $userToken->token = Str::random(64);
141
        $userToken->type = UserToken::TYPE_REMEMBER_ME;
142
        $userToken->expire_on = Carbon::now()->addDays($days)->format('Y-m-d H:i:s');
143
144
        $userToken->save();
145
146
        return $userToken->token;
147
    }
148
149
    /**
150
     * Login user with remembered token
151
     *
152
     * @param $token
153
     *
154
     * @return User|null
155
     */
156
    public function loginUserWithRememberToken($token)
157
    {
158
        return User::whereHas('userTokens', function ($query) use ($token) {
159
            $query->where('token', $token)
160
                ->where('expire_on', '>=', Carbon::now()->format('Y-m-d H:i:s'));
161
        })->first();
162
    }
163
164
    /**
165
     * Update remember token valability when used on login
166
     *
167
     * @param $token
168
     * @param int $days
169
     */
170
    public function updateRememberTokenValability($token, $days = 14)
171
    {
172
        $userToken = UserToken::where('token', $token)
173
            ->where('type', UserToken::TYPE_REMEMBER_ME)
174
            ->first();
175
176
        if ($userToken) {
177
            $userToken->expire_on = Carbon::now()->addDays($days)->format('Y-m-d H:i:s');
178
179
            $userToken->save();
180
        }
181
    }
182
183
    /**
184
     * Validate request on facebook login
185
     *
186
     * @param Request $request
187
     *
188
     * @return ReturnedValidator
189
     */
190
    public function validateFacebookLoginRequest(Request $request)
191
    {
192
        $rules = [
193
            'facebookId' => 'required',
194
            'accessToken' => 'required',
195
        ];
196
197
        $messages = [
198
            'facebookId.required' => TranslationCode::ERROR_FACEBOOK_ID_REQUIRED,
199
            'accessToken.required' => TranslationCode::ERROR_ACCESS_TOKEN_REQUIRED
200
        ];
201
202
        return Validator::make($request->all(), $rules, $messages);
203
    }
204
205
    /**
206
     * Validate request on twitter login
207
     *
208
     * @param Request $request
209
     *
210
     * @return ReturnedValidator
211
     */
212
    public function validateTwitterLoginRequest(Request $request)
213
    {
214
        $rules = [
215
            'twitterId' => 'required',
216
            'accessToken' => 'required',
217
        ];
218
219
        $messages = [
220
            'twitterId.required' => TranslationCode::ERROR_TWITTER_ID_REQUIRED,
221
            'accessToken.required' => TranslationCode::ERROR_ACCESS_TOKEN_REQUIRED
222
        ];
223
224
        return Validator::make($request->all(), $rules, $messages);
225
    }
226
227
    /**
228
     * Validate request on google login
229
     *
230
     * @param Request $request
231
     *
232
     * @return ReturnedValidator
233
     */
234
    public function validateGoogleLoginRequest(Request $request)
235
    {
236
        $rules = [
237
            'googleId' => 'required',
238
            'accessToken' => 'required',
239
        ];
240
241
        $messages = [
242
            'googleId.required' => TranslationCode::ERROR_GOOGLE_ID_REQUIRED,
243
            'accessToken.required' => TranslationCode::ERROR_ACCESS_TOKEN_REQUIRED
244
        ];
245
246
        return Validator::make($request->all(), $rules, $messages);
247
    }
248
249
    /**
250
     * Login user with social
251
     *
252
     * @param SocialiteUser $socialUser
253
     * @param Language $language
254
     * @param string $socialId
255
     *
256
     * @return User
257
     */
258
    public function loginUserWithSocial(SocialiteUser $socialUser, Language $language, string $socialId)
259
    {
260
        $user = User::where(function ($query) use ($socialUser, $socialId) {
261
            $query->where($socialId, $socialUser->getId())
262
                ->orWhereEncrypted('email', $socialUser->getEmail());
263
        })->first();
264
265
266
        if (!$user) {
267
            $user = new User();
268
269
            $user->language_id = $language->id;
270
            $user->name = $socialUser->getName();
271
            $user->email = $socialUser->getEmail();
272
273
            if ($socialUser->getAvatar()) {
274
                $baseService = new BaseService();
275
276
                $path = 'uploads/users/';
277
                File::makeDirectory($path, 0777, true, true);
278
279
                $generatedPictureName = time() . '.jpg';
280
281
                $pictureData = $baseService->processImage($path, $socialUser->getAvatar(), $generatedPictureName, true, true);
282
283
                if ($pictureData) {
284
                    $user->picture = $pictureData;
285
                }
286
            }
287
        }
288
289
        $user->status = User::STATUS_CONFIRMED;
290
        $user->$socialId = $socialUser->getId();
291
292
        $user->save();
293
294
        return $user;
295
    }
296
297
    /**
298
     * Validate request on register
299
     *
300
     * @param Request $request
301
     *
302
     * @return ReturnedValidator
303
     */
304
    public function validateRegisterRequest(Request $request)
305
    {
306
        $rules = [
307
            'name' => 'required|alpha_spaces',
308
            'email' => 'required|email|unique_binary:users,email',
309
            'password' => 'required|min:6'
310
        ];
311
312
        $messages = [
313
            'name.required' => TranslationCode::ERROR_NAME_REQUIRED,
314
            'name.alpha_spaces' => TranslationCode::ERROR_NAME_ALPHA_SPACES,
315
            'email.required' => TranslationCode::ERROR_EMAIL_REQUIRED,
316
            'email.email' => TranslationCode::ERROR_EMAIL_INVALID,
317
            'email.unique_binary' => TranslationCode::ERROR_EMAIL_REGISTERED,
318
            'password.required' => TranslationCode::ERROR_PASSWORD_REQUIRED,
319
            'password.min' => TranslationCode::ERROR_PASSWORD_MIN6
320
        ];
321
322
        return Validator::make($request->all(), $rules, $messages);
323
    }
324
325
    /**
326
     * Validate request on update user
327
     *
328
     * @param Request $request
329
     *
330
     * @return ReturnedValidator
331
     */
332
    public function validateUpdateUserRequest(Request $request)
333
    {
334
        $rules = [
335
            'name' => 'required|alpha_spaces',
336
            'email' => 'required|email',
337
            'newPassword' => 'required_with:oldPassword|min:6',
338
            'language' => 'required|exists:languages,id'
339
        ];
340
341
        $messages = [
342
            'name.required' => TranslationCode::ERROR_NAME_REQUIRED,
343
            'name.alpha_spaces' => TranslationCode::ERROR_NAME_ALPHA_SPACES,
344
            'email.required' => TranslationCode::ERROR_EMAIL_REQUIRED,
345
            'email.email' => TranslationCode::ERROR_EMAIL_INVALID,
346
            'newPassword.required_with' => TranslationCode::ERROR_OLD_PASSWORD_REQUIRED,
347
            'newPassword.min' => TranslationCode::ERROR_PASSWORD_MIN6,
348
            'language.required' => TranslationCode::ERROR_LANGUAGE_REQUIRED,
349
            'language.exists' => TranslationCode::ERROR_LANGUAGE_EXISTS,
350
        ];
351
352
        return Validator::make($request->all(), $rules, $messages);
353
    }
354
355
    /**
356
     * Update logged user
357
     *
358
     * @param User $user
359
     * @param Request $request
360
     */
361
    public function updateLoggedUser(User &$user, Request $request)
362
    {
363
        $email = $request->get('email');
364
        $confirmEmail = false;
365
366
        if ($user->email !== $email) {
367
            $user->email = $email;
368
            $user->status = User::STATUS_EMAIL_UNCONFIRMED;
369
            $user->activation_code = strtoupper(Str::random(6));
370
371
            $confirmEmail = true;
372
        }
373
374
        if ($request->has('newPassword')) {
375
            $user->password = Hash::make($request->get('newPassword'));
376
        }
377
378
        $user->name = $request->get('name');
379
380
        /** @var Language $language */
381
        $language = Language::where('id', $request->get('language'))->first();
382
        $user->language_id = $language->id;
383
384
        if ($confirmEmail) {
385
            $emailService = new EmailService();
386
387
            $emailService->sendEmailConfirmationCode($user, $language->code);
388
        }
389
390
        $user->save();
391
    }
392
393
    /**
394
     * Validate request on update user picture
395
     *
396
     * @param Request $request
397
     *
398
     * @return ReturnedValidator
399
     */
400
    public function validateUpdateUserPictureRequest(Request $request)
401
    {
402
        $rules = [
403
            'picture' => 'required|image',
404
        ];
405
406
        $messages = [
407
            'picture.required' => TranslationCode::ERROR_PICTURE_REQUIRED,
408
            'picture.image' => TranslationCode::ERROR_PICTURE_IMAGE
409
        ];
410
411
        return Validator::make($request->all(), $rules, $messages);
412
    }
413
414
    /**
415
     * Change logged user picture
416
     *
417
     * @param UploadedFile $picture
418
     */
419
    public function updateLoggedUserPicture(UploadedFile $picture)
420
    {
421
        /** @var User $user */
422
        $user = Auth::user();
423
424
        $pictureExtension = $picture->getClientOriginalExtension();
425
        $generatedPictureName = str_replace(' ', '_', $user->name) . '_' . time() . '.' . $pictureExtension;
426
427
        $path = 'uploads/users/';
428
        File::makeDirectory($path, 0777, true, true);
429
430
        $baseService = new BaseService();
431
432
        $pictureData = $baseService->processImage($path, $picture, $generatedPictureName, true);
433
434
        if ($pictureData) {
435
            if ($user->picture !== '') {
436
                $oldPictureData = json_decode($user->picture, true);
437
438
                foreach ($oldPictureData as $oldPicture) {
439
                    if ($oldPicture && file_exists($oldPicture)) {
440
                        unlink($oldPicture);
441
                    }
442
                }
443
            }
444
445
            $user->picture = $pictureData;
446
        }
447
448
        $user->save();
449
    }
450
451
    /**
452
     * Validate request on forgot password
453
     *
454
     * @param Request $request
455
     *
456
     * @return ReturnedValidator
457
     */
458
    public function validateForgotPasswordRequest(Request $request)
459
    {
460
        $rules = [
461
            'email' => 'required|email|exists_binary:users,email'
462
        ];
463
464
        $messages = [
465
            'email.required' => TranslationCode::ERROR_EMAIL_REQUIRED,
466
            'email.email' => TranslationCode::ERROR_EMAIL_INVALID,
467
            'email.exists_binary' => TranslationCode::ERROR_EMAIL_NOT_REGISTERED
468
        ];
469
470
        return Validator::make($request->all(), $rules, $messages);
471
    }
472
473
    /**
474
     * Send code on email for forgot password
475
     *
476
     * @param User $user
477
     * @param Language $language
478
     */
479
    public function sendForgotPasswordCode(User $user, Language $language)
480
    {
481
        $user->forgot_code = strtoupper(Str::random(6));
482
        $user->forgot_time = Carbon::now()->format('Y-m-d H:i:s');
483
484
        /** @var EmailService $emailService */
485
        $emailService = new EmailService();
486
487
        $emailService->sendForgotPasswordCode($user, $language->code);
488
489
        $user->save();
490
    }
491
492
    /**
493
     * Validate request on forgot change password
494
     *
495
     * @param Request $request
496
     *
497
     * @return ReturnedValidator
498
     */
499
    public function validateChangePasswordRequest(Request $request)
500
    {
501
        $rules = [
502
            'email' => 'required|email|exists_binary:users,email',
503
            'code' => 'required',
504
            'password' => 'required|min:6'
505
        ];
506
507
        $messages = [
508
            'email.required' => TranslationCode::ERROR_EMAIL_REQUIRED,
509
            'email.email' => TranslationCode::ERROR_EMAIL_INVALID,
510
            'email.exists_binary' => TranslationCode::ERROR_EMAIL_NOT_REGISTERED,
511
            'code.required' => TranslationCode::ERROR_CODE_REQUIRED,
512
            'password.required' => TranslationCode::ERROR_PASSWORD_REQUIRED,
513
            'password.min' => TranslationCode::ERROR_PASSWORD_MIN6
514
        ];
515
516
        return Validator::make($request->all(), $rules, $messages);
517
    }
518
519
    /**
520
     * Update user password after reset
521
     *
522
     * @param $user
523
     * @param $password
524
     */
525
    public function updatePassword($user, $password)
526
    {
527
        $user->forgot_code = null;
528
        $user->forgot_time = null;
529
        $user->password = Hash::make($password);
530
531
        $user->save();
532
    }
533
534
    /**
535
     * Register user
536
     *
537
     * @param Request $request
538
     * @param Language $language
539
     */
540
    public function registerUser(Request $request, Language $language)
541
    {
542
        $user = new User();
543
544
        $user->name = $request->get('name');
545
        $user->email = $request->get('email');
546
        $user->password = $request->get('password');
547
        $user->status = User::STATUS_UNCONFIRMED;
548
        $user->language_id = $language->id;
549
        $user->activation_code = strtoupper(Str::random(6));
550
551
        /** @var EmailService $emailService */
552
        $emailService = new EmailService();
553
554
        $emailService->sendActivationCode($user, $language->code);
555
556
        $user->save();
557
    }
558
559
    /**
560
     * Validate activate account
561
     *
562
     * @param Request $request
563
     *
564
     * @return ReturnedValidator
565
     */
566
    public function validateActivateAccountOrChangeEmailRequest(Request $request)
567
    {
568
        $rules = [
569
            'email' => 'required|email',
570
            'code' => 'required'
571
        ];
572
573
        $messages = [
574
            'email.required' => TranslationCode::ERROR_EMAIL_REQUIRED,
575
            'email.email' => TranslationCode::ERROR_EMAIL_INVALID,
576
            'code.required' => TranslationCode::ERROR_CODE_REQUIRED
577
        ];
578
579
        return Validator::make($request->all(), $rules, $messages);
580
    }
581
582
    /**
583
     * Activate user account on register or on change email
584
     *
585
     * @param $email
586
     * @param $code
587
     *
588
     * @return bool
589
     */
590
    public function activateUserAccount($email, $code)
591
    {
592
        /** @var User $user */
593
        $user = User::whereEncrypted('email', $email)
594
            ->where('activation_code', $code)
595
            ->first();
596
597
        if (!$user) {
0 ignored issues
show
introduced by
$user is of type App\Models\User, thus it always evaluated to true.
Loading history...
598
            return false;
599
        }
600
601
        $user->status = User::STATUS_CONFIRMED;
602
        $user->activation_code = null;
603
604
        $user->save();
605
606
        return true;
607
    }
608
609
    /**
610
     * Validate request on resend
611
     *
612
     * @param Request $request
613
     *
614
     * @return ReturnedValidator
615
     */
616
    public function validateResendActivationCodeRequest(Request $request)
617
    {
618
        $rules = [
619
            'email' => 'required|email'
620
        ];
621
622
        $messages = [
623
            'email.required' => TranslationCode::ERROR_EMAIL_REQUIRED,
624
            'email.email' => TranslationCode::ERROR_EMAIL_INVALID
625
        ];
626
627
        return Validator::make($request->all(), $rules, $messages);
628
    }
629
630
    /**
631
     * Resend registration mail
632
     *
633
     * @param Request $request
634
     * @param Language $language
635
     *
636
     * @return array|bool
637
     */
638
    public function resendRegisterMail(Request $request, Language $language)
639
    {
640
        $user = User::whereEncrypted('email', $request->get('email'))->first();
641
642
        if (!$user) {
643
            return ['email' => TranslationCode::ERROR_EMAIL_NOT_REGISTERED];
644
        }
645
646
        if ($user->status === User::STATUS_CONFIRMED) {
647
            return ['account' => TranslationCode::ERROR_ACCOUNT_UNACTIVATED];
648
        }
649
650
        if ($user->updated_at->addMinute() > Carbon::now()) {
651
            return ['code' => TranslationCode::ERROR_CODE_SEND_COOLDOWN];
652
        }
653
654
        /** @var EmailService $emailService */
655
        $emailService = new EmailService();
656
657
        $emailService->sendActivationCode($user, $language->code);
658
659
        $user->updated_at = Carbon::now()->format('Y-m-d H:i:s');
660
        $user->save();
661
662
        return false;
663
    }
664
}
665