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/EmailVerificationHandler.php +46 -2 1.10.1 → 2.4.5 View file →
@@ -8,10 +8,43 @@
8 8
9 9
10 10 class EmailVerificationHandler
11 11 {
12 + /**
13 + * Must match the "valid for 10 minutes" copy in the email below.
14 + */
15 + const CODE_TTL_SECONDS = 10 * MINUTE_IN_SECONDS;
16 +
12 17 public static function sendSignupEmailVerificationHtml($formData)
13 18 {
19 + $email = strtolower(trim($formData['email']));
20 +
21 + // The email bucket is the main throttle against mail-bombing an address. The IP
22 + // bucket is looser because offices and NATs share IPs.
23 + $ipKey = 'fs_signup_verify_ip_' . wp_hash(Helper::getIp());
24 + $emailKey = 'fs_signup_verify_email_' . wp_hash($email);
25 +
26 + /*
27 + * Site-wide hourly cap on signup verification mail, for attackers who rotate
28 + * both IP and address. Tripping it blocks signup for everyone, so keep it well
29 + * above organic traffic.
30 + *
31 + * @since v2.2.2
32 + * @param int $limit Signup verification emails allowed site-wide per hour.
33 + */
34 + $globalLimit = (int) apply_filters('fluent_support/signup_verification_hourly_limit', 100);
35 +
36 + // Check the global bucket last. Short-circuiting means only requests that pass
37 + // the IP and email gates count toward it, so one IP can't exhaust it.
38 + if (Helper::hitRateLimit($ipKey, 20)
39 + || Helper::hitRateLimit($emailKey, 5)
40 + || Helper::hitRateLimit('fs_signup_verify_global', $globalLimit, HOUR_IN_SECONDS)
41 + ) {
42 + wp_send_json([
43 + 'message' => __('Too many verification code requests. Please try again later.', 'fluent-support')
44 + ], 429);
45 + }
46 +
14 47 try {
15 48 $verifcationCode = str_pad(random_int(100123, 900987), 6, 0, STR_PAD_LEFT);
16 49 } catch (\Exception $e) {
17 50 $verifcationCode = str_pad(wp_rand(100123, 900987), 6, 0, STR_PAD_LEFT);
@@ -24,29 +57,39 @@
24 57
25 58 $data = array(
26 59 'login_hash' => $hash,
27 60 'status' => 'issued',
61 + 'email' => strtolower(trim($formData['email'])),
28 62 'ip_address' => Helper::getIp(),
29 63 'use_type' => 'signup_verification',
30 64 'used_count' => 0,
31 65 'two_fa_code_hash' => wp_hash_password($verifcationCode),
32 - 'valid_till' => date('Y-m-d H:i:s', current_time('timestamp') + 10 * 60),
66 + 'valid_till' => gmdate('Y-m-d H:i:s', current_time('timestamp') + self::CODE_TTL_SECONDS),
33 67 'created_at' => current_time('mysql'),
34 68 'updated_at' => current_time('mysql')
35 69 );
36 70
37 - Meta::insert([
71 + $savedRecord = Meta::create([
38 72 'object_type' => 'fs_login_hashes',
39 73 'key' => $hash,
40 74 'value' => maybe_serialize($data)
41 75 ]);
42 76
77 + if (!$savedRecord || !$savedRecord->exists) {
78 + wp_send_json([
79 + 'message' => __('Unable to send verification code. Please try again later.', 'fluent-support')
80 + ], 500);
81 + }
82 +
83 + // translators: %s is the site name
43 84 $mailSubject = apply_filters("fluent_support/signup_verification_mail_subject", sprintf(__('Your registration verification code for %s', 'fluent-support'), get_bloginfo('name')));
44 85
45 86 $pStart = '<p style="font-family: Arial, sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px;">';
46 87
88 + // translators: %s is the user's first name
47 89 $message = $pStart . sprintf(__('Hello %s,', 'fluent-support'), Arr::get($formData, 'first_name')) . '</p>' .
48 90 $pStart . __('Thank you for registering with us! To complete the setup of your account, please enter the verification code below on the registration page.', 'fluent-support') . '</p>' .
91 + // translators: %s is the verification code
49 92 $pStart . '<b>' . sprintf(__('Verification Code: %s', 'fluent-support'), $verifcationCode) . '</b></p>' .
50 93 '<br />' .
51 94 $pStart . __('This code is valid for 10 minutes and is meant to ensure the security of your account. If you did not initiate this request, please ignore this email.', 'fluent-support') . '</p>';
52 95
@@ -66,8 +109,9 @@
66 109 ob_start();
67 110 ?>
68 111 <div class="fs_signup_verification">
69 112 <div class="fs_field_group fs_field_verification">
113 + <?php // translators: %s is the email address ?>
70 114 <p><?php echo esc_html(sprintf(__('A verification code has been sent to %s. Please provide the code below:', 'fluent-support'), $formData['email'])); ?></p>
71 115 <input type="hidden" name="_email_verification_hash" value="<?php echo esc_attr($hash); ?>"/>
72 116 <div class="fs_field_label is-required">
73 117 <label for="fs_field_verification"><?php esc_html_e('Verification Code', 'fluent-support'); ?></label>