PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.2.1
Fluent Support – Helpdesk & Customer Support Ticket System v2.2.1
2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 All 67 releases
fluent-support / app / Http / Controllers / AuthController.php

AuthController.php in Fluent Support – Helpdesk & Customer Support Ticket System 2.2.1, at app/Http/Controllers/AuthController.php

762 lines 25.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Http\Controllers;
4
5 use FluentSupport\App\Models\Meta;
6 use FluentSupport\App\Services\Helper;
7 use FluentSupport\Framework\Support\Arr;
8 use FluentSupport\Framework\Http\Request\Request;
9 use FluentSupport\App\Hooks\Handlers\AuthHandler;
10 use FluentSupport\App\Hooks\Handlers\ReCaptchaHandler;
11 use FluentSupport\App\Hooks\Handlers\TwoFaHandler;
12 use FluentSupport\App\Hooks\Handlers\EmailVerificationHandler;
13
14
15 class AuthController extends Controller
16 {
17 /**
18 * signUp method will create new user submitted data from sign up form
19 * @param Request $request
20 * @return \WP_REST_Response
21 * @throws \FluentSupport\Framework\Validator\ValidationException
22 */
23 public function signup(Request $request)
24 {
25
26 if(Helper::getAuthProvider() !== 'fluent_support') {
27 return $this->sendError([
28 'message' => __('You are not allowed to signup using this form', 'fluent-support')
29 ]);
30 }
31
32 if (!wp_verify_nonce($request->getSafe('_fsupport_signup_nonce', 'sanitize_text_field'), 'fluent_support_signup_nonce')) {
33 return $this->sendError([
34 'message' => __('Security verification failed. Please try again', 'fluent-support')
35 ]);
36 }
37
38 $fields = AuthHandler::getSignupFields();
39
40 $rules = $this->getRules($fields);
41
42 $messages = $this->getMessages($rules);
43
44 /*
45 * Filter user signup form data
46 *
47 * @since v1.0.0
48 * @param array $formData
49 */
50 $formData = apply_filters('fluent_support/signup_form_data', $request->all());
51
52 /*
53 * Action before validate user signup
54 *
55 * @since v1.0.0
56 * @param array $formData
57 */
58 do_action('fluent_support/before_signup_validation', $formData);
59
60 $checkRecaptchaAvailability = $this->isRecaptchaApplicable('signup_form');
61 if ($checkRecaptchaAvailability && !$formData['_email_verification_hash']) {
62 $validateCaptcha = ReCaptchaHandler::validateRecaptcha($formData['g-recaptcha-response']);
63 if (!$validateCaptcha) {
64 return $this->response([
65 'message' => __('Your recaptcha is not verified', 'fluent-support')
66 ], 422);
67 }
68 }
69
70 $this->validate($formData, $rules, $messages);
71
72 if (empty($formData['_email_verification_token'])) {
73 $tokenHtml = EmailVerificationHandler::sendSignupEmailVerificationHtml($formData);
74
75 return $this->response([
76 'verification_html' => $tokenHtml
77 ]);
78 } else {
79 $token = $formData['_email_verification_token'];
80 $verificationHash = $formData['_email_verification_hash'];
81
82 $logHashMeta = Meta::where('object_type', 'fs_login_hashes',)
83 ->where('key', $verificationHash)
84 ->first();
85
86 if (!$logHashMeta) {
87 wp_send_json([
88 'message' => __('Please provide a valid verification code that was sent to your email address', 'fluent-support')
89 ], 422);
90 }
91
92 $logHash = Helper::safeUnserialize($logHashMeta->value);
93
94 if (!$logHash) {
95 wp_send_json([
96 'message' => __('Please provide a valid verification code that was sent to your email address', 'fluent-support')
97 ], 422);
98 }
99
100 // check if it got expired or not
101 $validTill = $logHash['valid_till'] ?? '';
102 if (($logHash['used_count'] ?? 0) > 5 || ($validTill && strtotime($validTill) < current_time('timestamp'))) {
103 wp_send_json([
104 'message' => __('Your verification code has been expired. Please try again', 'fluent-support')
105 ], 422);
106 }
107
108 if (!wp_check_password($token, $logHash['two_fa_code_hash'])) {
109
110 $logHash['used_count'] += 1;
111 Meta::where('key', $logHash['login_hash'])->update([
112 'value' => maybe_serialize($logHash)
113 ]);
114
115 wp_send_json([
116 'message' => __('Please provide a valid verification code that was sent to your email address', 'fluent-support')
117 ], 422);
118 }
119
120 $logHash['used_count'] += 1;
121 $logHash['status'] = 'used';
122
123 Meta::where('key', $logHash['login_hash'])->update([
124 'value' => maybe_serialize($logHash)
125 ]);
126 }
127
128 /*
129 * Action After validate user signup validation success
130 *
131 * @since v1.0.0
132 * @param array $formData
133 */
134 do_action('fluent_support/after_signup_validation', $formData);
135
136 $userId = $this->createUser($formData);
137
138 if (is_wp_error($userId)) {
139 return $this->response(
140 apply_filters(
141 'fluent_support/signup_create_user_error',
142 ['error' => $userId->get_error_message()]
143 ), 423);
144 }
145
146 /*
147 * Action After creating WP user from ticket sign up form
148 *
149 * @since v1.0.0
150 * @param array $formData
151 */
152 do_action('fluent_support/after_creating_user');
153
154 $this->maybeUpdateUser($userId, $formData);
155 $this->addUserMetaData($userId, $formData);
156 $this->assignRole($userId);
157 $this->login($userId);
158
159 /*
160 * Filter for user signup complete message and redirect
161 *
162 * @since v1.0.0
163 * @param array $response
164 */
165 $response = apply_filters('fluent_support/signup_complete_response', [
166 'message' => __('Successfully registered to the site.', 'fluent-support'),
167 'redirect' => Arr::get($formData, '__redirect_to', Helper::getPortalBaseUrl())
168 ]);
169
170 return $this->response($response);
171 }
172
173 /**
174 * handleLogin method will perform login functionality and redirect
175 * @param Request $request
176 * @return \WP_REST_Response
177 */
178 public function handleLogin(Request $request)
179 {
180 if(Helper::getAuthProvider() !== 'fluent_support') {
181 return $this->sendError([
182 'message' => __('You are not allowed to login using this form', 'fluent-support')
183 ]);
184 }
185
186 if (!wp_verify_nonce($request->getSafe('_support_login_nonce', 'sanitize_text_field'), 'fsupport_login_nonce')) {
187 return $this->response([
188 'message' => __('Security verification failed', 'fluent-support')
189 ], 403);
190 }
191
192 $data = $request->all();
193
194 $checkRecaptchaAvailability = $this->isRecaptchaApplicable('login_form');
195 if ($checkRecaptchaAvailability) {
196 $validateCaptcha = ReCaptchaHandler::validateRecaptcha($data['g-recaptcha-response']);
197
198 if (!$validateCaptcha) {
199 return $this->response([
200 'message' => __('Your recaptcha is not verified', 'fluent-support')
201 ], 422);
202 }
203 }
204
205 if (empty($data['pwd']) || empty($data['log'])) {
206 return $this->response([
207 'message' => __('Email and Password is required', 'fluent-support')
208 ], 403);
209 }
210 $redirectUrl = Helper::getPortalBaseUrl();
211 if ($redirect = $request->getSafe('redirect_to', 'sanitize_text_field')) {
212 $redirectUrl = wp_validate_redirect($redirect, $redirectUrl);
213 }
214
215 if (get_current_user_id()) { // user already registered
216 return $this->sendSuccess([
217 'redirect' => $redirectUrl
218 ]);
219 }
220
221 $email = sanitize_user($data['log']);
222 $password = trim($data['pwd'] ?? '');
223
224 if (is_email($email)) {
225 $user = get_user_by('email', $email);
226 } else {
227 $user = get_user_by('login', $email);
228 }
229
230 // Rate limiting: per-IP bucket (5 attempts) + per-account bucket (20 attempts)
231 $ip = Helper::getIp();
232 $ipKey = $user
233 ? 'fs_login_ip_' . wp_hash($user->ID . '|' . $ip)
234 : 'fs_login_ip_' . wp_hash(strtolower($email) . '|' . $ip);
235 $accountKey = $user
236 ? 'fs_login_act_' . wp_hash($user->ID)
237 : 'fs_login_act_' . wp_hash(strtolower($email));
238
239 $ipAttempts = get_transient($ipKey);
240 $accountAttempts = get_transient($accountKey);
241
242 if (($ipAttempts !== false && $ipAttempts >= 5) || ($accountAttempts !== false && $accountAttempts >= 20)) {
243 return $this->sendError([
244 'message' => __('Too many login attempts. Please try again after 15 minutes.', 'fluent-support')
245 ], 429);
246 }
247
248 if (!$user) {
249 $user = new \WP_Error('authentication_failed', __('<strong>Error</strong>: Invalid username, email address or incorrect password.', 'fluent-support'));
250
251 do_action('wp_login_failed', $email, $user);
252 $this->incrementLoginAttempts($ipKey);
253 $this->incrementLoginAttempts($accountKey);
254
255 return $this->response([
256 'message' => __('Email or Password is not valid. Please try again', 'fluent-support')
257 ], 403);
258
259 }
260
261 $twoFactorEnabled = Helper::getBusinessSettings('enable_two_fa');
262 if ('yes' === $twoFactorEnabled) {
263 (new TwoFaHandler)->maybe2FaRedirect($user);
264 }
265
266 if (apply_filters('fluent_support_use_native_login', true)) {
267 $user = wp_signon();
268 if (is_wp_error($user)) {
269 $this->incrementLoginAttempts($ipKey);
270 $this->incrementLoginAttempts($accountKey);
271 return $this->response([
272 'message' => $user->get_error_message()
273 ], 403);
274 }
275
276 // Clear rate limits for the authenticated user
277 $authIpKey = 'fs_login_ip_' . wp_hash($user->ID . '|' . $ip);
278 $authAccountKey = 'fs_login_act_' . wp_hash($user->ID);
279 delete_transient($authIpKey);
280 delete_transient($authAccountKey);
281 return $this->sendSuccess([
282 'redirect' => $redirectUrl
283 ]);
284 }
285
286 if (wp_check_password($password, $user->user_pass, $user->ID)) {
287 delete_transient($ipKey);
288 delete_transient($accountKey);
289 $this->login($user->ID);
290 return $this->sendSuccess([
291 'redirect' => $redirectUrl
292 ]);
293 }
294
295 $this->incrementLoginAttempts($ipKey);
296 $this->incrementLoginAttempts($accountKey);
297
298 return $this->response([
299 'message' => __('<strong>Error</strong>: Invalid username, email address or incorrect password.', 'fluent-support')
300 ], 403);
301 }
302
303 private function incrementLoginAttempts($rateLimitKey)
304 {
305 $attempts = get_transient($rateLimitKey);
306 if ($attempts === false) {
307 set_transient($rateLimitKey, 1, 15 * MINUTE_IN_SECONDS);
308 } else {
309 set_transient($rateLimitKey, $attempts + 1, 15 * MINUTE_IN_SECONDS);
310 }
311 }
312
313 public function isRecaptchaApplicable($formName)
314 {
315 $reCaptchaSettingsData = Meta::where('object_type', '_fs_recaptcha_settings')->first();
316 if(!isset($reCaptchaSettingsData->value)){
317 return false;
318 }
319 $reCaptchaData = Helper::safeUnserialize($reCaptchaSettingsData->value, []);
320 if(!isset($reCaptchaData['is_enabled']) || !isset($reCaptchaData['formContainingReCaptcha'])){
321 return false;
322 }
323 $isEnabled = filter_var($reCaptchaData['is_enabled'], FILTER_VALIDATE_BOOLEAN);
324 if (!$isEnabled) {
325 return false;
326 }
327 $formContainingReCaptcha = $reCaptchaData['formContainingReCaptcha'];
328 return 'yes' === $formContainingReCaptcha[$formName];
329 }
330
331 private function nativeLoginHandler($user, $info, $redirectUrl = '')
332 {
333 if (!$redirectUrl) {
334 $redirectUrl = Helper::getPortalBaseUrl();
335 }
336
337 $secure_cookie = is_ssl();
338 if (!$secure_cookie && !force_ssl_admin()) {
339 if (get_user_option('use_ssl', $user->ID)) {
340 $secure_cookie = true;
341 force_ssl_admin(true);
342 }
343 }
344
345 if (class_exists('\Limit_Login_Attempts')) {
346 global $limit_login_attempts_obj;
347 $limit_login_attempts_try = $limit_login_attempts_obj->wp_authenticate_user($user, false);
348 if (is_wp_error($limit_login_attempts_try)) {
349 return $this->response([
350 'message' => implode('<br/>', $limit_login_attempts_try->get_error_messages())
351 ], 403);
352 }
353 }
354
355 $user_signon = wp_signon($info, $secure_cookie);
356
357 // Note: No sanitization needed here as we're only checking emptiness, not using the cookie value
358 if (!is_wp_error($user_signon) && empty($_COOKIE[LOGGED_IN_COOKIE])) {
359 if (headers_sent()) {
360 return $this->response([
361 // translators: %1$s is the URL to WordPress cookies documentation, %2$s is the URL to WordPress support forums
362 'message' => sprintf(__('<strong>ERROR</strong>: Cookies are blocked due to unexpected output. For help, please see <a href="%1$s">this documentation</a> or try the <a href="%2$s">support forums</a>.', 'fluent-support'),
363 'https://codex.wordpress.org/Cookies', 'https://wordpress.org/support/')
364 ], 403);
365 }
366 }
367
368 if (is_wp_error($user_signon)) {
369 $errorMessage = __('Email or Password is not valid. Please try again', 'fluent-support');
370
371 if (class_exists('Limit_Login_Attempts')) {
372 global $limit_login_attempts_obj;
373 if ($limit_login_attempts_obj) {
374 $limit_login_attempts_obj->limit_login_failed($user->user_login);
375 $msg = $limit_login_attempts_obj->get_message();
376 if ($msg) {
377 $errorMessage = $msg;
378 }
379 }
380 }
381
382 return $this->response([
383 'message' => $errorMessage
384 ], 403);
385 }
386
387 // WP Last Login plugin compatibility
388 if (class_exists('\Obenland_Wp_Last_Login')) {
389 update_user_meta($user_signon->ID, 'wp-last-login', time());
390 }
391
392 return $this->sendSuccess([
393 'redirect' => $redirectUrl
394 ]);
395 }
396
397 /**
398 * getRules method will prepare the rules for the input field
399 * @param array $fields
400 * @return mixed
401 */
402 protected function getRules($fields = [])
403 {
404 $rules = [];
405
406 foreach ($fields as $fieldName => $field) {
407 if (array_key_exists('required', $field)) {
408 $rules[$fieldName] = 'required';
409 }
410
411 $pipe = array_key_exists($fieldName, $rules) ? '|' : '';
412
413 if ($field['type'] === 'email') {
414 $rules[$fieldName] = $rules[$fieldName] . $pipe . 'email';
415 } elseif ($field['type'] === 'password') {
416 $rules[$fieldName] = $rules[$fieldName] . $pipe . 'min:8';
417 }
418 }
419 /*
420 * Filter user signup validation rules
421 *
422 * @since v1.0.0
423 * @param array $rules
424 */
425 return apply_filters('fluent_support/signup_validation_rules', $rules);
426 }
427
428
429 public function resetPassword(Request $request)
430 {
431
432 if(Helper::getAuthProvider() !== 'fluent_support') {
433 return $this->sendError([
434 'message' => __('You are not allowed to reset password using this form', 'fluent-support')
435 ]);
436 }
437
438 $errors = new \WP_Error();
439
440 if (!wp_verify_nonce($request->getSafe('_fsupport_reset_pass_nonce', 'sanitize_text_field'), 'fluent_support_reset_pass_nonce')) {
441 return $this->sendError([
442 'message' => __('Security verification failed. Please try again', 'fluent-support')
443 ]);
444 }
445
446 $usernameOrEmail = trim(wp_unslash($request->getSafe('user_login', 'sanitize_text_field')));
447
448 if (!$usernameOrEmail) {
449 return $this->sendError([
450 'message' => 'Username or email is required'
451 ]);
452 }
453
454 $user_data = get_user_by('email', $usernameOrEmail);
455
456 if (!$user_data) {
457 $user_data = get_user_by('login', $usernameOrEmail);
458 }
459
460 if (!$user_data) {
461 return $this->sendError([
462 'message' => __('Invalid username or email', 'fluent-support')
463 ]);
464 }
465
466 $user_data = apply_filters('lostpassword_user_data', $user_data, $errors);
467
468 do_action('lostpassword_post', $errors, $user_data);
469
470 $errors = apply_filters('lostpassword_errors', $errors, $user_data);
471
472 if ($errors->has_errors()) {
473 return $this->sendError([
474 'message' => $errors->get_error_message()
475 ]);
476 }
477
478 if (!$user_data) {
479 return $this->sendError([
480 'message' => __('<strong>Error</strong>: There is no account with that username or email address.', 'fluent-support')
481 ]);
482 }
483
484 if (is_multisite() && !is_user_member_of_blog($user_data->ID, get_current_blog_id())) {
485
486 return $this->sendError([
487 'message' => __('<strong>Error</strong>: Invalid username or email', 'fluent-support')
488 ]);
489 }
490
491 // Redefining user_login ensures we return the right case in the email.
492 $user_login = $user_data->user_login;
493
494 do_action('retrieve_password', $user_login);
495
496 $allow = apply_filters('allow_password_reset', true, $user_data->ID);
497
498 if (!$allow) {
499 return $this->sendError([
500 'message' => __('Password reset is not allowed for this user', 'fluent-support')
501 ]);
502 }
503
504 if (is_wp_error($allow)) {
505 return $this->sendError([
506 'message' => $allow->get_error_message()
507 ]);
508 }
509
510
511 /*
512 * Filter reset password link text
513 *
514 * @since v1.5.7
515 * @param string $linkText
516 */
517 // translators: %s is the site name
518 $linkText = apply_filters("fluent_support/reset_password_link", sprintf(__('Reset your password for %s', 'fluent-support'), get_bloginfo('name')));
519
520 $resetUrl = add_query_arg([
521 'action' => 'rp',
522 'key' => get_password_reset_key($user_data),
523 'login' => rawurlencode($user_data->user_login)
524 ], wp_login_url());
525
526 $resetLink = '<a href="' . $resetUrl . '">' . $linkText . '</a>';
527
528 /*
529 * Filter reset password email subject
530 *
531 * @since v1.5.7
532 * @param string $mailSubject
533 */
534 // translators: %s is the site name
535 $mailSubject = apply_filters("fluent_support/reset_password_mail_subject", sprintf(__('Reset your password for %s support portal', 'fluent-support'), get_bloginfo('name')));
536
537 // translators: %s is the user's first name
538 $message = '<p>' . sprintf(__('Hi %s,', 'fluent-support'), $user_data->first_name) . '</p>' .
539 '<p>' . __('Someone has requested a new password for the following account on WordPress:', 'fluent-support') . '</p>' .
540 // translators: %s is the username
541 '<p>' . sprintf(__('Username: %s', 'fluent-support'), $user_login) . '</p>' .
542 '<p>' . $resetLink . '</p>' .
543 '<p>' . __('If you did not request to reset your password, please ignore this email.', 'fluent-support') . '</p>';
544
545 /*
546 * Filter reset password email body text
547 *
548 * @since v1.5.7
549 * @param string $message
550 * @param object $user
551 * @param string $resetLink
552 */
553 $message = apply_filters('fluent_support/reset_password_message', $message, $user_data, $resetLink);
554
555 $headers = array('Content-Type: text/html; charset=UTF-8');
556
557 wp_mail($user_data->user_email, $mailSubject, $message, $headers);
558
559 return $this->sendSuccess([
560 'message' => __('Please check your email for the reset link', 'fluent-support')
561 ]);
562 }
563
564 /**
565 * getMessages message will return the validation message regarding sign up or sign in
566 * @param array $rules
567 * @return mixed
568 */
569 protected function getMessages($rules = [])
570 {
571 /*
572 * Filter user signup validation message
573 *
574 * @since v1.0.0
575 * @param array $arg
576 * @param array $rules
577 */
578 return apply_filters('fluent_support/signup_validation_messages', [], $rules);
579 }
580
581 /**
582 * createUser method will create new user
583 * @param array $formData
584 * @return mixed
585 */
586 public function createUser($formData = [])
587 {
588 /*
589 * Filter user signup email
590 *
591 * @since v1.0.0
592 * @param string $email
593 */
594 $email = apply_filters('fluent_support/signup_email', Arr::get($formData, 'email'));
595
596 /*
597 * Filter user signup username
598 *
599 * @since v1.0.0
600 * @param string $username
601 */
602 $userName = apply_filters('fluent_support/signup_username', Arr::get($formData, 'username'));
603
604 if (empty($formData['password'])) {
605 $password = wp_generate_password(16, true, true);
606 } else {
607 $password = $formData['password'];
608 }
609
610 /*
611 * Filter user signup password
612 *
613 * @since v1.0.0
614 * @param string $password
615 */
616 $password = apply_filters('fluent_support/signup_password', $password);
617
618 /*
619 * Action before creating WP user using Fluent Support signup form
620 *
621 * @since v1.0.0
622 * @param string $userName
623 * @param string $password
624 * @param string $email
625 */
626 do_action('fluent_support/before_creating_user', $userName, $password, $email);
627
628 $userId = wp_create_user($userName, $password, $email);
629
630 if (is_wp_error($userId)) {
631 return false;
632 }
633
634 return $userId;
635
636 }
637
638 /**
639 * maybeUpdateUser method will update user information if exists
640 * @param $userId
641 * @param $formData
642 */
643 public function maybeUpdateUser($userId, $formData)
644 {
645 $firstName = Arr::get($formData, 'first_name', '');
646 $lastName = Arr::get($formData, 'last_name', '');
647 $name = trim($firstName . ' ' . $lastName);
648
649 $data = array_filter([
650 'ID' => $userId,
651 'user_nicename' => $name,
652 'display_name' => $name,
653 'first_name' => $firstName,
654 'last_name' => $lastName,
655 ]);
656
657 if ($name) {
658 /*
659 * Action before updating a customer/user
660 *
661 * @since v1.0.0
662 * @param array $data
663 */
664 do_action('fluent_support/before_updating_user', $data);
665
666 /*
667 * Filter user updatable data
668 *
669 * @since v1.0.0
670 * @param $data
671 */
672 $updateUserData = apply_filters('fluent_support/update_user_data', $data);
673 wp_update_user($updateUserData);
674
675 /*
676 * Action after updating a customer/user
677 *
678 * @since v1.0.0
679 * @param array $data
680 */
681 do_action('fluent_support/after_updating_user', $data);
682 }
683 }
684
685 public function addUserMetaData($userId, $formData) {
686 $customFieldsKey = apply_filters('fluent_support/custom_registration_form_fields_key', Helper::getBusinessSettings('custom_registration_form_field'));
687
688 if (empty($customFieldsKey)) {
689 return;
690 }
691
692 foreach ($customFieldsKey as $key) {
693 if (isset($formData[$key])) {
694 $fieldValue = $formData[$key];
695 update_user_meta($userId, $key, $fieldValue);
696 }
697 }
698 }
699
700 /**
701 * assignRole method will assign role to a given user id
702 * @param $userId
703 */
704 protected function assignRole($userId)
705 {
706 $user = new \WP_User($userId);
707
708 /*
709 * Action before assigning role to registered user
710 *
711 * @since v1.0.0
712 * @param array $data
713 */
714 do_action('fluent_support/before_assigning_role', $user);
715 /*
716 * Filter user assignable role after signup
717 *
718 * @since v1.0.0
719 * @param string $setRole WordPress user role key
720 */
721 $setRole = apply_filters('fluent_support/user_role', 'subscriber');
722 $user->set_role($setRole);
723
724 /*
725 * Action after assigning role to registered user
726 *
727 * @since v1.0.0
728 * @param array $data
729 */
730 do_action('fluent_support/after_assigning_role', $user);
731 }
732
733
734 /**
735 * login method will clear existing cookies and set new cookie for a given user id
736 * @param $userId
737 */
738 protected function login($userId)
739 {
740 /*
741 * Action before login
742 *
743 * @since v1.0.0
744 * @param integer $userId
745 */
746 do_action('fluent_support/before_logging_in_user', $userId);
747
748 wp_clear_auth_cookie();
749 wp_set_current_user($userId);
750 wp_set_auth_cookie($userId);
751
752 /*
753 * Action after login
754 *
755 * @since v1.0.0
756 * @param integer $userId
757 */
758 do_action('fluent_support/after_logging_in_user', $userId);
759 }
760
761 }
762