PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.5
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.5
2.4.5 2.4.0 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 All 69 releases
← All changes | app/Hooks/Handlers/AuthHandler.php +503 -77 1.4.0 → 2.4.5 View file →
@@ -2,86 +2,280 @@
2 2
3 3 namespace FluentSupport\App\Hooks\Handlers;
4 4
5 5 use FluentSupport\App\App;
6 +use FluentSupport\App\Modules\PermissionManager;
7 +use FluentSupport\App\Services\FluentAuthBridge;
6 8 use FluentSupport\App\Services\Helper;
9 +use FluentSupport\App\Services\Includes\CountryNames;
10 +use FluentSupport\App\Vite;
7 11 use FluentSupport\Framework\Support\Arr;
12 +use FluentSupport\App\Models\Meta;
8 13
9 14 class AuthHandler
10 15 {
11 16
17 + protected $loaded = false;
18 +
12 19 public function init()
13 20 {
14 21 add_shortcode('fluent_support_login', array($this, 'loginForm'));
15 22 add_shortcode('fluent_support_signup', array($this, 'registrationForm'));
16 23 add_shortcode('fluent_support_auth', array($this, 'authForm'));
24 + add_shortcode('fluent_support_reset_password', array($this, 'restPasswordForm'));
25 + add_action('wp_ajax_fluent_support_renew_rest_nonce', [$this, 'maybeRenewNonce']);
26 +
27 + FluentAuthBridge::register();
17 28 }
18 29
30 + /**
31 + * @param $attributes
32 + * @return string
33 + */
19 34 public function loginForm($attributes)
20 35 {
36 + if (get_current_user_id()) {
37 + return '<p>' . __('You are already logged in.', 'fluent-support') . '</p>';
38 + }
39 +
21 40 $attributes = $this->getShortcodes($attributes);
41 + if (!empty($attributes['redirect-to'])) {
42 + $redirect = $attributes['redirect-to'];
43 + } else {
44 + $redirect = Helper::getPortalBaseUrl();
45 + }
46 +
47 +
22 48 $this->handleAlreadyLoggedIn($attributes);
23 49
24 - $app = App::getInstance();
25 - $assets = $app['url.assets'];
26 - wp_enqueue_style('fluent_support_login_style', $assets . 'admin/css/all_public.css');
27 - wp_enqueue_script('fluent_support_login_helper', $assets . 'portal/js/login_helper.js');
28 - $return = '<div class="fst_login_wrapper">';
50 + if ($this->authProvider() == 'fluent_auth') {
51 + $attributes['redirect_to'] = $redirect;
52 + return $this->renderFluentAuthForms($attributes);
53 + }
29 54
55 + $this->loadAssets();
56 +
57 + $return = '<div class="fst_login_form_auth_wrapper">';
58 + $return .= '<div id="fst_login_form" class="fst_login_wrapper">';
59 +
60 +
61 + /*
62 + * Filter login form
63 + *
64 + * @since v1.0.0
65 + *
66 + * @param array $loginArgs
67 + */
30 68 $loginArgs = apply_filters('fluent_support/login_form_args', [
31 69 'echo' => false,
32 - 'redirect' => Helper::getPortalBaseUrl(),
70 + 'redirect' => $redirect,
33 71 'remember' => true,
34 - 'value_remember' => true
72 + 'value_remember' => true,
35 73 ]);
36 74
37 75 $return .= wp_login_form($loginArgs);
76 +
77 + if ($attributes['show-signup'] == 'true') {
78 + $return .= '<p style="text-align: center">'
79 + . __('Not registered?', 'fluent-support')
80 + . ' <a href="#" id="fs_show_signup">'
81 + . __('Create an account', 'fluent-support')
82 + . '</a></p>';
83 + }
84 +
85 + if ($attributes['show-reset-password'] == 'true') {
86 + $return .= '<p style="text-align: center">'
87 + . __('Forgot your password?', 'fluent-support')
88 + . ' <a href="#" id="fs_show_reset_password">'
89 + . __('Reset password', 'fluent-support')
90 + . '</a></p>';
91 + }
92 +
38 93 $return .= '</div>';
94 +
95 + if ($attributes['show-signup'] == 'true') {
96 + $return .= do_shortcode('[fluent_support_signup hide=true]');
97 + }
98 +
99 + if ($attributes['show-reset-password'] == 'true') {
100 + $return .= do_shortcode('[fluent_support_reset_password hide=true]');
101 + }
102 +
103 + $return .= '</div>';
39 104 return $return;
40 105 }
41 106
107 + /**
108 + * @param $attributes
109 + * @return string
110 + */
42 111 public function registrationForm($attributes)
43 112 {
113 + if (get_current_user_id()) {
114 + return '<p>' . __('You are already logged in.', 'fluent-support') . '</p>';
115 + }
116 +
44 117 $attributes = $this->getShortcodes($attributes);
45 118 $this->handleAlreadyLoggedIn($attributes);
46 119
47 - $app = App::getInstance();
48 - $assets = $app['url.assets'];
49 - wp_enqueue_style('fluent_support_login_style', $assets . 'admin/css/all_public.css');
50 - wp_enqueue_script('fluent_support_login_helper', $assets . 'portal/js/login_helper.js');
120 + if (!Helper::isSignupEnabled()) {
121 + if ($attributes['hide'] == 'true') {
122 + return '';
123 + }
51 124
52 - wp_localize_script('fluent_support_login_helper', 'fluentSupportPublic', [
53 - 'signup' => rest_url($app->config->get('app.rest_namespace') . '/' . $app->config->get('app.rest_version')) . '/signup'
54 - ]);
125 + return '<p>' . __('User registration is not enabled on this site.', 'fluent-support') . '</p>';
126 + }
55 127
128 + if ($this->authProvider() == 'fluent_auth') {
129 + return FluentAuthBridge::render(function () use ($attributes) {
130 + return (new \FluentAuth\App\Hooks\Handlers\CustomAuthHandler())->registrationForm($attributes);
131 + }, $attributes['redirect_to']);
132 + }
133 +
134 + $customFieldsKey = Helper::getCustomRegistrationFieldKeys();
135 +
136 + if (!empty($customFieldsKey)) {
137 + add_filter('fluent_support/registration_form_fields', function($fields) use ($customFieldsKey) {
138 + return $this->addCustomFieldsToRegistrationForm($fields,$customFieldsKey);
139 + });
140 + }
141 +
56 142 $registrationFields = static::getSignupFields();
143 + $hide = $attributes['hide'] == 'true' ? 'hide' : '';
57 144
58 - $registrationForm = '<div class="fst_registration_wrapper"><form id="fstRegistrationForm" class="fs_registration_form" method="post" name="fs_registration_form">';
145 + $this->loadAssets($hide);
59 146
147 + return $this->buildRegistrationForm($registrationFields, $hide, $attributes);
148 + }
149 +
150 + private function buildRegistrationForm($registrationFields, $hide, $attributes)
151 + {
152 + $registrationForm = '<div class="fst_registration_wrapper ' . $hide . '"><form id="fstRegistrationForm" class="fs_registration_form" method="post" name="fs_registration_form">';
153 +
60 154 foreach ($registrationFields as $fieldName => $registrationField) {
61 155 $registrationForm .= $this->renderField($fieldName, $registrationField);
62 156 }
63 157
64 - $registrationForm .= '<input type="hidden" name="__redirect_to" value="' . $attributes['redirect-to'] . '">';
65 - $registrationForm .= '<button type="submit" id="fst_submit">' . $this->submitBtnLoadingSvg() . '<span>' . __('Signup', 'fluent-support') . '</span></button>';
158 + $registrationForm .= '<input type="hidden" name="__redirect_to" value="' . esc_url($attributes['redirect-to']) . '">';
159 + $registrationForm .= '<input type="hidden" name="_fsupport_signup_nonce" value="' . wp_create_nonce('fluent_support_signup_nonce') . '">';
160 + $registrationForm .= '<button type="submit" id="fst_submit">' . $this->submitBtnLoadingSvg() . '<span>' . __('Signup', 'fluent-support') . '</span></button>';
66 161
67 - $registrationForm .= '</form></div>';
162 + $registrationForm .= '</form>';
68 163
164 + $registrationForm .= apply_filters('fluent_support/before_registration_form_close', '', $registrationFields, $attributes);
165 +
166 + if ($hide) {
167 + $registrationForm .= '<p style="text-align: center">'
168 + . __('Already have an account?', 'fluent-support')
169 + . ' <a href="#" id="fs_show_login">'
170 + . __('Login', 'fluent-support')
171 + . '</a></p>';
172 + }
173 +
174 + $registrationForm .= '</div>';
175 +
69 176 return $registrationForm;
70 177 }
71 178
179 + public function restPasswordForm($attributes)
180 + {
181 + if (get_current_user_id()) {
182 + return '<p>' . __('You are already logged in.', 'fluent-support') . '</p>';
183 + }
184 +
185 + $attributes = $this->getShortcodes($attributes);
186 +
187 + if ($this->authProvider() == 'fluent_auth') {
188 + return FluentAuthBridge::render(function () use ($attributes) {
189 + return (new \FluentAuth\App\Hooks\Handlers\CustomAuthHandler())->restPasswordForm($attributes);
190 + }, $attributes['redirect_to']);
191 + }
192 +
193 + $this->handleAlreadyLoggedIn($attributes);
194 +
195 + $resetPasswordFields = static::resetPasswordFields();
196 + $hide = $attributes['hide'] == 'true' ? 'hide' : '';
197 +
198 + $this->loadAssets($hide);
199 +
200 + return $this->buildResetPassForm($resetPasswordFields, $hide, $attributes);
201 + }
202 +
203 + private function buildResetPassForm($resetPasswordFields, $hide, $attributes)
204 + {
205 + $restePasswordForm = '<div class="fst_reset_pass_wrapper ' . $hide . '"><form id="fstResetPasswordForm" class="fs_reset_pass_form" method="post" name="fs_reset_pass_form">';
206 +
207 + foreach ($resetPasswordFields as $fieldName => $resetPasswordField) {
208 + $restePasswordForm .= $this->renderField($fieldName, $resetPasswordField);
209 + }
210 +
211 + $restePasswordForm .= '<input type="hidden" name="__redirect_to" value="' . esc_url($attributes['redirect-to']) . '">';
212 + $restePasswordForm .= '<input type="hidden" name="_fsupport_reset_pass_nonce" value="' . wp_create_nonce('fluent_support_reset_pass_nonce') . '">';
213 + $restePasswordForm .= '<button type="submit" id="fst_reset_pass">' . $this->submitBtnLoadingSvg() . '<span>' . __('Reset Password', 'fluent-support') . '</span></button>';
214 +
215 + $restePasswordForm .= '</form>';
216 +
217 + $restePasswordForm .= '</div>';
218 +
219 + return $restePasswordForm;
220 + }
221 +
222 + /**
223 + * Login form with signup and reset links, or FluentAuth's form when it is the provider.
224 + *
225 + * @param $attributes
226 + * @return string
227 + */
72 228 public function authForm($attributes)
73 229 {
74 - $authForm = '<div class="fst_auth_wrapper">';
230 + if (get_current_user_id()) {
231 + // translators: %s is the URL to the support portal
232 + return '<p>' . sprintf(__('You are already logged in. <a href="%s">Go to support portal</a>', 'fluent-support'), Helper::getPortalBaseUrl()) . '</p>';
233 + }
75 234
76 - $authForm .= do_shortcode('[fluent_support_login]');
77 - $authForm .= do_shortcode('[fluent_support_signup]');
235 + $attributes = $this->getShortcodes($attributes, true);
78 236
79 - $authForm .= '</div>';
237 + if ($this->authProvider() == 'fluent_auth') {
238 + return $this->renderFluentAuthForms($attributes);
239 + }
80 240
81 - return $authForm;
241 + return $this->loginForm($attributes);
82 242 }
83 243
244 + /**
245 + * FluentAuth's login form, plus its signup and reset forms (hidden) when the shortcode
246 + * shows them. Its "Create an Account" and "Reset Password" links open a form that must
247 + * already be on the page, and its own authForm() always adds reset, so we pick the
248 + * forms here. FluentAuth renders and processes each one.
249 + *
250 + * @param array $attributes
251 + * @return string
252 + */
253 + private function renderFluentAuthForms($attributes)
254 + {
255 + return FluentAuthBridge::render(function () use ($attributes) {
256 + $handler = new \FluentAuth\App\Hooks\Handlers\CustomAuthHandler();
257 + $hidden = array_merge($attributes, ['hide' => 'true']);
258 +
259 + $html = '<div class="fls_auth_wrapper">' . $handler->loginForm($attributes);
260 +
261 + if ($attributes['show-signup'] == 'true') {
262 + $html .= $handler->registrationForm($hidden);
263 + }
264 +
265 + if ($attributes['show-reset-password'] == 'true') {
266 + $html .= $handler->restPasswordForm($hidden);
267 + }
268 +
269 + return $html . '</div>';
270 + }, $attributes['redirect_to']);
271 + }
272 +
273 + /**
274 + * @param $fieldName
275 + * @param $field
276 + * @return string
277 + */
84 278 private function renderField($fieldName, $field)
85 279 {
86 280 $fieldType = Arr::get($field, 'type');
87 281 $isRequired = Arr::get($field, 'required');
@@ -86,82 +280,219 @@
86 280 $fieldType = Arr::get($field, 'type');
87 281 $isRequired = Arr::get($field, 'required');
88 282 $isRequired = $isRequired ? 'is-required' : '';
89 283
90 - $textTypes = ['text', 'email', 'password'];
284 + $html = '<div class="fst_field_group fst_field_' . $fieldName . '">';
91 285
92 - $html = '<div class="fst_field_group fst_field_'.$fieldName.'">';
93 - if($label = Arr::get($field, 'label')) {
94 - $html .= '<div class="fst_field_label ' . $isRequired . '"><label for="'.Arr::get($field, 'id').'">'.$label.'</label></div>';
286 + if ($label = Arr::get($field, 'label')) {
287 + $html .= '<div class="fst_field_label ' . $isRequired . '"><label for="' . Arr::get($field, 'id') . '">' . $label . '</label></div>';
95 288 }
96 289
97 - if(in_array($fieldType, $textTypes)) {
290 + $textTypes = ['text', 'email', 'password', 'number', 'date'];
291 + $selectTypes = ['select'];
98 292
99 - $inputAtts = array_filter([
100 - 'type' => esc_attr($fieldType),
101 - 'id' => esc_attr(Arr::get($field, 'id')),
102 - 'placeholder' => esc_attr(Arr::get($field, 'placeholder')),
103 - 'name' => esc_attr($fieldName)
104 - ]);
293 + if (in_array($fieldType, $textTypes)) {
294 + $html .= $this->renderTextInput($fieldName, $field);
295 + } elseif (in_array($fieldType, $selectTypes)) {
296 + $html .= $this->renderSelectInput($fieldName, $field);
297 + } else {
298 + return '';
299 + }
105 300
106 - $atts = '';
301 + $html = $html . '</div>';
107 302
108 - foreach ($inputAtts as $attKey => $att) {
109 - $atts .= $attKey.'="'.$att.'" ';
110 - }
303 + return '<div class="fst_registration_fields">' . $html . '</div>';
304 + }
111 305
112 - if(Arr::get($field, 'required')) {
113 - $atts .= 'required';
114 - }
306 + private function renderTextInput($fieldName, $field)
307 + {
308 + $inputAtts = array_filter([
309 + 'type' => esc_attr(Arr::get($field, 'type', '')),
310 + 'id' => esc_attr(Arr::get($field, 'id', '')),
311 + 'placeholder' => esc_attr(Arr::get($field, 'placeholder', '')),
312 + 'name' => esc_attr($fieldName),
313 + 'required' => Arr::get($field, 'required') ? 'required' : '',
314 + ]);
115 315
116 - $html .= '<div class="fs_input_wrap"><input '.$atts.'/></div>';
117 - } else {
118 - return '';
316 + $atts = '';
317 +
318 + foreach ($inputAtts as $attKey => $att) {
319 + $atts .= $attKey . '="' . $att . '" ';
119 320 }
120 321
121 - return $html.'</div>';
322 + return '<div class="fs_input_wrap"><input ' . $atts . ' /></div>';
122 323 }
123 324
325 + /**
326 + * @param string $fieldName
327 + * @param array $field Field config with options and attributes.
328 + * @return string
329 + */
330 + private function renderSelectInput($fieldName, $field)
331 + {
332 + $choices = Arr::get($field, 'options', []);
333 + $placeholder = Arr::get($field, 'placeholder', '');
334 +
335 + $options = '<option value="" disabled selected>' . esc_attr($placeholder) . '</option>';
336 +
337 + foreach ($choices as $value => $optionData) {
338 + $options .= '<option value="' . esc_attr($value) . '">' . esc_attr($optionData) . '</option>';
339 + }
340 +
341 + $selectAtts = [
342 + 'id' => esc_attr(Arr::get($field, 'id', '')),
343 + 'name' => esc_attr($fieldName),
344 + 'required' => Arr::get($field, 'required') ? 'required' : '',
345 + ];
346 +
347 + $select = '<div class="fs_input_wrap"><select ' . $this->renderAttributes($selectAtts) . '>' . $options . '</select></div>';
348 +
349 + return $select;
350 + }
351 +
352 + private function renderAttributes($attributes)
353 + {
354 + $atts = '';
355 +
356 + foreach ($attributes as $attKey => $att) {
357 + $atts .= $attKey . '="' . $att . '" ';
358 + }
359 +
360 + return $atts;
361 + }
362 +
363 + /**
364 + * @return mixed
365 + */
124 366 public static function getSignupFields()
125 367 {
368 + /*
369 + * Filter signup form field
370 + *
371 + * @since v1.0.0
372 + *
373 + * @param array $fields Form fields
374 + */
126 375 return apply_filters('fluent_support/registration_form_fields', [
127 376 'first_name' => [
128 - 'required' => true,
129 - 'type' => 'text',
130 - 'label' => __('First name', 'fluent-support'),
131 - 'id' => 'fst_first_name',
377 + 'required' => true,
378 + 'type' => 'text',
379 + 'label' => __('First name', 'fluent-support'),
380 + 'id' => 'fst_first_name',
132 381 'placeholder' => __('First name', 'fluent-support')
133 382 ],
134 - 'last_name' => [
135 - 'type' => 'text',
136 - 'label' => __('Last Name', 'fluent-support'),
137 - 'id' => 'fst_last_name',
383 + 'last_name' => [
384 + 'type' => 'text',
385 + 'label' => __('Last Name', 'fluent-support'),
386 + 'id' => 'fst_last_name',
138 387 'placeholder' => __('Last name', 'fluent-support')
139 388 ],
140 - 'username' => [
141 - 'required' => true,
142 - 'type' => 'text',
143 - 'label' => __('Username', 'fluent-support'),
144 - 'id' => 'fst_username',
389 + 'username' => [
390 + 'required' => true,
391 + 'type' => 'text',
392 + 'label' => __('Username', 'fluent-support'),
393 + 'id' => 'fst_username',
145 394 'placeholder' => __('Username', 'fluent-support')
146 395 ],
147 - 'email' => [
148 - 'required' => true,
149 - 'type' => 'email',
150 - 'label' => __('Email Address', 'fluent-support'),
151 - 'id' => 'fst_email',
396 + 'email' => [
397 + 'required' => true,
398 + 'type' => 'email',
399 + 'label' => __('Email Address', 'fluent-support'),
400 + 'id' => 'fst_email',
152 401 'placeholder' => __('Your Email Address', 'fluent-support')
153 402 ],
154 - 'password' => [
155 - 'required' => true,
156 - 'type' => 'password',
157 - 'label' => __('Password', 'fluent-support'),
158 - 'id' => 'fst_password',
403 + 'password' => [
404 + 'required' => true,
405 + 'type' => 'password',
406 + 'label' => __('Password', 'fluent-support'),
407 + 'id' => 'fst_password',
159 408 'placeholder' => __('Password', 'fluent-support')
160 409 ]
161 410 ]);
162 411 }
163 412
413 + private function addCustomFieldsToRegistrationForm($fields, $customFieldsKey) {
414 + $customFields = $this->allCustomFields();
415 +
416 + foreach ($customFieldsKey as $key) {
417 + if (isset($customFields[$key])) {
418 + $fields[$key] = $customFields[$key];
419 + }
420 + }
421 +
422 + return $fields;
423 + }
424 +
425 + public static function allCustomFields(): array {
426 + $countryList = CountryNames::get();
427 +
428 + return apply_filters('fluent_support/custom_registration_form_fields', [
429 + 'address_line_1' => [
430 + 'required' => false,
431 + 'type' => 'text',
432 + 'label' => __('Address Line 1', 'fluent-support'),
433 + 'id' => 'fst_address_line_1',
434 + 'placeholder' => __('Address Line 1', 'fluent-support'),
435 + ],
436 + 'address_line_2' => [
437 + 'required' => false,
438 + 'type' => 'text',
439 + 'label' => __('Address Line 2', 'fluent-support'),
440 + 'id' => 'fst_address_line_2',
441 + 'placeholder' => __('Address Line 2', 'fluent-support'),
442 + ],
443 + 'city' => [
444 + 'required' => false,
445 + 'type' => 'text',
446 + 'label' => __('City', 'fluent-support'),
447 + 'id' => 'fst_city',
448 + 'placeholder' => __('City', 'fluent-support'),
449 + ],
450 + 'zip' => [
451 + 'required' => false,
452 + 'type' => 'text',
453 + 'label' => __('Zip', 'fluent-support'),
454 + 'id' => 'fst_zip',
455 + 'placeholder' => __('Zip', 'fluent-support'),
456 + ],
457 + 'state' => [
458 + 'required' => false,
459 + 'type' => 'text',
460 + 'label' => __('State', 'fluent-support'),
461 + 'id' => 'fst_state',
462 + 'placeholder' => __('State', 'fluent-support'),
463 + ],
464 + 'country' => [
465 + 'required' => false,
466 + 'type' => 'select',
467 + 'label' => __('Country', 'fluent-support'),
468 + 'id' => 'fst_country',
469 + 'placeholder' => __('Select a Country', 'fluent-support'),
470 + 'options' => $countryList,
471 + ],
472 + ]);
473 + }
474 +
475 + public static function resetPasswordFields()
476 + {
477 + /*
478 + * Filter reset password form field
479 + *
480 + * @since v1.5.7
481 + *
482 + * @param array $fields Form fields
483 + */
484 + return apply_filters('fluent_support/reset_password_form', [
485 + 'user_login' => [
486 + 'required' => true,
487 + 'type' => 'text',
488 + 'label' => __('Email Address', 'fluent-support'),
489 + 'id' => 'fst_reset_email',
490 + 'placeholder' => __('Your Email Address', 'fluent-support')
491 + ]
492 + ]);
493 + }
494 +
164 495 protected function submitBtnLoadingSvg()
165 496 {
166 497 $loadingIcon = '<svg version="1.1" id="loader-1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
167 498 width="40px" height="20px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
@@ -175,19 +506,49 @@
175 506 repeatCount="indefinite"/>
176 507 </path>
177 508 </svg>';
178 509
179 - return apply_filters('fluent-support/signup_loading_icon', $loadingIcon);
510 + /*
511 + * Filter signup form loading icon
512 + *
513 + * @since v1.0.0
514 + *
515 + * @param string $loadingIcon this accepts html element
516 + */
517 + return apply_filters('fluent_support/signup_loading_icon', $loadingIcon);
180 518 }
181 519
182 - protected function getShortcodes($attributes)
520 + protected function getShortcodes($attributes, $isAuthForm = false)
183 521 {
184 - $shortCodeDefaults = apply_filters('fluent-support/auth_shortcode_defaults', [
185 - 'auto-redirect' => false,
186 - 'redirect-to' => Helper::getPortalBaseUrl()
522 + /*
523 + * Filter the default attributes of the auth shortcodes.
524 + *
525 + * @since v1.0.0
526 + *
527 + * @param array $shortCodeDefaults
528 + */
529 + $shortCodeDefaults = apply_filters('fluent_support/auth_shortcode_defaults', [
530 + 'auto-redirect' => false,
531 + 'redirect-to' => Helper::getPortalBaseUrl(),
532 + 'hide' => false,
533 + 'show-signup' => $isAuthForm ? 'true' : 'false',
534 + 'show-reset-password' => $isAuthForm ? 'true' : 'false',
187 535 ]);
188 536
189 - return shortcode_atts($shortCodeDefaults, $attributes);
537 + $attributes = shortcode_atts($shortCodeDefaults, $attributes);
538 +
539 + // No signup form or link while the site does not allow registration.
540 + if (!Helper::isSignupEnabled()) {
541 + $attributes['show-signup'] = 'false';
542 + }
543 +
544 + if (isset($attributes['redirect-to'])) {
545 + $attributes['redirect-to'] = esc_url_raw($attributes['redirect-to']);
546 + $attributes['redirect_to'] = $attributes['redirect-to'];
547 + }
548 +
549 + return $attributes;
550 +
190 551 }
191 552
192 553 protected function handleAlreadyLoggedIn($attributes)
193 554 {
@@ -195,16 +556,81 @@
195 556 if ($attributes['auto-redirect'] === 'true') {
196 557 $redirect = $attributes['redirect-to'];
197 558 ?>
198 559 <script type="text/javascript">
199 - document.addEventListener("DOMContentLoaded", function() {
200 - var redirect = "<?php echo $redirect; ?>";
560 + document.addEventListener("DOMContentLoaded", function () {
561 + var redirect = "<?php echo esc_url($redirect); ?>";
201 562 window.location.replace(redirect);
202 563 });
203 564 </script>
204 565 <?php
205 566 }
567 + die();
568 + }
569 + }
206 570
207 - die();
571 + public function loadAssets($hide = '')
572 + {
573 + if ($this->loaded) {
574 + return false;
208 575 }
576 +
577 + $app = App::getInstance();
578 + $assets = $app['url.assets'];
579 +
580 + if (is_rtl()) {
581 + wp_enqueue_style('fluent_support_login_style_rtl', $assets . 'admin/css/all_public-rtl.css', [], FLUENT_SUPPORT_VERSION);
582 + } else {
583 + wp_enqueue_style('fluent_support_login_style', Vite::getEnqueuePath('admin/css/all_public.css'), [], FLUENT_SUPPORT_VERSION);
584 + }
585 +
586 + wp_enqueue_script('fluent_support_login_helper', Vite::getEnqueuePath('portal/js/login_helper.js'), [], FLUENT_SUPPORT_VERSION);
587 +
588 + $reCaptchaSettingsData = Meta::where('object_type', '_fs_recaptcha_settings')->first();
589 + $reCaptchaData = ($reCaptchaSettingsData) ? Helper::safeUnserialize($reCaptchaSettingsData->value, []) : '';
590 +
591 + if (!empty($reCaptchaData) && isset($reCaptchaData['is_enabled']) && $reCaptchaData['is_enabled'] == "true") {
592 + unset($reCaptchaData['secretKey']);
593 + $recaptchaVersion = $reCaptchaData["reCaptcha_version"];
594 + $reCaptchaApiUrl = 'https://www.google.com/recaptcha/api.js';
595 +
596 + if ("recaptcha_v3" === $recaptchaVersion) {
597 + $reCaptchaApiUrl .= '?render=' . $reCaptchaData["siteKey"];
598 + }
599 +
600 + wp_enqueue_script('recaptcha', $reCaptchaApiUrl);
601 + }
602 +
603 + wp_localize_script('fluent_support_login_helper', 'fluentSupportPublic', [
604 + 'signup' => rest_url($app->config->get('app.rest_namespace') . '/' . $app->config->get('app.rest_version')) . '/signup',
605 + 'login' => rest_url($app->config->get('app.rest_namespace') . '/' . $app->config->get('app.rest_version')) . '/login',
606 + 'nonce' => wp_create_nonce('wp_rest'),
607 + 'hide' => $hide,
608 + 'redirect_fallback' => Helper::getPortalBaseUrl(),
609 + 'fsupport_login_nonce' => wp_create_nonce('fsupport_login_nonce'),
610 + 'resetPass' => rest_url($app->config->get('app.rest_namespace') . '/' . $app->config->get('app.rest_version')) . '/reset_pass',
611 + 'reCaptchaSettingsData' => $reCaptchaData,
612 + 'fs_two_fa' => rest_url($app->config->get('app.rest_namespace') . '/' . $app->config->get('app.rest_version')) . '/two_fa'
613 + ]);
614 +
615 +
616 + $this->loaded = true;
617 + }
618 +
619 + public function maybeRenewNonce()
620 + {
621 + if (!PermissionManager::currentUserPermissions()) {
622 + wp_send_json([
623 + 'error' => __('You do not have permission to do this.', 'fluent-support')
624 + ], 403);
625 + }
626 +
627 + wp_send_json([
628 + 'nonce' => wp_create_nonce('wp_rest')
629 + ], 200);
630 + }
631 +
632 + private function authProvider()
633 + {
634 + return \FluentSupport\App\Services\Helper::getAuthProvider();
209 635 }
210 636 }