| 1 |
<?php |
| 2 |
|
| 3 |
/** |
| 4 |
* Login Lockdown |
| 5 |
* https://wploginlockdown.com/ |
| 6 |
* (c) WebFactory Ltd, 2022 - 2024, www.webfactoryltd.com |
| 7 |
*/ |
| 8 |
|
| 9 |
class LoginLockdown_Tab_Login_Form extends LoginLockdown |
| 10 |
{ |
| 11 |
static function display() |
| 12 |
{ |
| 13 |
$tabs[] = array('id' => 'tab_login_basic', 'class' => 'tab-content', 'label' => __('Basic', 'login-lockdown'), 'callback' => array(__CLASS__, 'tab_basic')); |
| 14 |
$tabs[] = array('id' => 'tab_login_advanced', 'class' => 'tab-content', 'label' => __('Advanced', 'login-lockdown'), 'callback' => array(__CLASS__, 'tab_advanced')); |
| 15 |
$tabs[] = array('id' => 'tab_login_tools', 'class' => 'tab-content', 'label' => __('Tools', 'login-lockdown'), 'callback' => array(__CLASS__, 'tab_tools')); |
| 16 |
|
| 17 |
echo '<div id="tabs_log" class="ui-tabs loginlockdown-tabs-2nd-level">'; |
| 18 |
echo '<ul>'; |
| 19 |
foreach ($tabs as $tab) { |
| 20 |
echo '<li><a href="#' . esc_attr($tab['id']) . '">' . esc_attr($tab['label']) . '</a></li>'; |
| 21 |
} |
| 22 |
echo '</ul>'; |
| 23 |
|
| 24 |
foreach ($tabs as $tab) { |
| 25 |
if (is_callable($tab['callback'])) { |
| 26 |
echo '<div style="display: none;" id="' . esc_attr($tab['id']) . '" class="' . esc_attr($tab['class']) . '">'; |
| 27 |
call_user_func($tab['callback']); |
| 28 |
echo '</div>'; |
| 29 |
} |
| 30 |
} // foreach |
| 31 |
|
| 32 |
echo '</div>'; // second level of tabs |
| 33 |
|
| 34 |
|
| 35 |
} // display |
| 36 |
|
| 37 |
static function tab_basic() |
| 38 |
{ |
| 39 |
$options = LoginLockdown_Setup::get_options(); |
| 40 |
|
| 41 |
echo '<table class="form-table"><tbody>'; |
| 42 |
|
| 43 |
echo '<tr valign="top"> |
| 44 |
<th scope="row"><label for="max_login_retries">Max Login Retries</label></th> |
| 45 |
<td><input type="number" class="regular-text" id="max_login_retries" name="' . esc_attr(LOGINLOCKDOWN_OPTIONS_KEY) . '[max_login_retries]" value="' . esc_attr($options['max_login_retries']) . '" />'; |
| 46 |
echo '<br><span>Number of failed login attempts within the "Retry Time Period Restriction" (defined below) needed to trigger a Lockdown.</span>'; |
| 47 |
echo '</td></tr>'; |
| 48 |
|
| 49 |
echo '<tr valign="top"> |
| 50 |
<th scope="row"><label for="retries_within">Retry Time Period Restriction</label></th> |
| 51 |
<td><input type="number" class="regular-text" id="retries_within" name="' . esc_attr(LOGINLOCKDOWN_OPTIONS_KEY) . '[retries_within]" value="' . esc_attr($options['retries_within']) . '" /> minutes'; |
| 52 |
echo '<br><span>The time in which failed login attempts are allowed before a lockdown occurs.</span>'; |
| 53 |
echo '</td></tr>'; |
| 54 |
|
| 55 |
echo '<tr valign="top"> |
| 56 |
<th scope="row"><label for="lockout_length">Lockout Length</label></th> |
| 57 |
<td><input type="number" class="regular-text" id="lockout_length" name="' . esc_attr(LOGINLOCKDOWN_OPTIONS_KEY) . '[lockout_length]" value="' . esc_attr($options['lockout_length']) . '" /> minutes'; |
| 58 |
echo '<br><span>The time a particular IP will be locked out once a lockdown has been triggered.</span>'; |
| 59 |
echo '</td></tr>'; |
| 60 |
|
| 61 |
echo '<tr valign="top"> |
| 62 |
<th scope="row"><label for="lockout_invalid_usernames">Log Failed Attempts With Non-existant Usernames</label></th> |
| 63 |
<td>'; |
| 64 |
LoginLockdown_Utility::create_toggle_switch('lockout_invalid_usernames', array('saved_value' => $options['lockout_invalid_usernames'], 'option_key' => LOGINLOCKDOWN_OPTIONS_KEY . '[lockout_invalid_usernames]')); |
| 65 |
echo '<br /><span>Log failed log in attempts with non-existant usernames the same way failed attempts with bad passwords are logged.</span>'; |
| 66 |
echo '</td></tr>'; |
| 67 |
|
| 68 |
echo '<tr valign="top"> |
| 69 |
<th scope="row"><label for="mask_login_errors">Mask Login Errors</label></th> |
| 70 |
<td>'; |
| 71 |
LoginLockdown_Utility::create_toggle_switch('mask_login_errors', array('saved_value' => $options['mask_login_errors'], 'option_key' => LOGINLOCKDOWN_OPTIONS_KEY . '[mask_login_errors]')); |
| 72 |
echo '<br /><span>Hide log in error details (such as invalid username, invalid password, invalid captcha value) to minimize data available to attackers.</span>'; |
| 73 |
echo '</td></tr>'; |
| 74 |
|
| 75 |
echo '<tr valign="top"> |
| 76 |
<th scope="row"><label for="global_block">Block Type</label></th> |
| 77 |
<td>'; |
| 78 |
echo '<label class="loginlockdown-radio-option">'; |
| 79 |
echo '<span class="radio-container"><input type="radio" name="' . esc_attr(LOGINLOCKDOWN_OPTIONS_KEY) . '[global_block]" id="global_block_global" value="1" ' . ($options['global_block'] == 1 ? 'checked' : '') . '><span class="radio"></span></span> Completely block website access'; |
| 80 |
echo '</label>'; |
| 81 |
|
| 82 |
echo '<label class="loginlockdown-radio-option">'; |
| 83 |
echo '<span class="radio-container"><input type="radio" name="' . esc_attr(LOGINLOCKDOWN_OPTIONS_KEY) . '[global_block]" id="global_block_login" value="0" ' . ($options['global_block'] != 1 ? 'checked' : '') . '><span class="radio"></span></span> Only block access to the login page'; |
| 84 |
echo '</label>'; |
| 85 |
echo '<span>Completely block website access for blocked IPs, or just blocking access to the login page.</span>'; |
| 86 |
echo '</td></tr>'; |
| 87 |
|
| 88 |
|
| 89 |
echo '<tr valign="top"> |
| 90 |
<th scope="row"><label for="block_message">Block Message</label></th> |
| 91 |
<td><input type="text" class="regular-text" id="block_message" name="' . esc_attr(LOGINLOCKDOWN_OPTIONS_KEY) . '[block_message]" value="' . esc_html($options['block_message']) . '" />'; |
| 92 |
echo '<br /><span>Message displayed to visitors blocked due to too many failed login attempts. Default: <i>We\'re sorry, but your IP has been blocked due to too many recent failed login attempts.</i></span>'; |
| 93 |
echo '</td></tr>'; |
| 94 |
|
| 95 |
$remote_addr = ''; |
| 96 |
if(isset($_SERVER['REMOTE_ADDR'])){ |
| 97 |
$remote_addr = sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])); |
| 98 |
} |
| 99 |
echo '<tr valign="top"> |
| 100 |
<th scope="row"><label for="whitelist">Whitelisted IPs</label></th> |
| 101 |
<td><textarea class="regular-text" id="whitelist" rows="6" name="' . esc_attr(LOGINLOCKDOWN_OPTIONS_KEY) . '[whitelist]">' . (is_array($options['whitelist']) ? esc_html(implode(PHP_EOL, $options['whitelist'])) : esc_html($options['whitelist'])) . '</textarea>'; |
| 102 |
echo '<br /><span>List of IP addresses that will never be blocked. Enter one IP per line.<br>Your current IP is: <code>' . esc_html($remote_addr) . '</code></span>'; |
| 103 |
echo '</td></tr>'; |
| 104 |
|
| 105 |
echo '<tr valign="top"> |
| 106 |
<th scope="row"><label for="show_credit_link">Show Credit Link</label></th> |
| 107 |
<td>'; |
| 108 |
LoginLockdown_Utility::create_toggle_switch('show_credit_link', array('saved_value' => $options['show_credit_link'], 'option_key' => LOGINLOCKDOWN_OPTIONS_KEY . '[show_credit_link]')); |
| 109 |
echo '<br /><span>Show a small "form protected by" link below the login form to help others learn about the free Login Lockdown plugin & protect their sites.</span>'; |
| 110 |
echo '</td></tr>'; |
| 111 |
|
| 112 |
echo '<tr><td></td><td>'; |
| 113 |
LoginLockdown_admin::footer_save_button(); |
| 114 |
echo '</td></tr>'; |
| 115 |
|
| 116 |
echo '</tbody></table>'; |
| 117 |
} |
| 118 |
|
| 119 |
static function tab_advanced() |
| 120 |
{ |
| 121 |
$options = LoginLockdown_Setup::get_options(); |
| 122 |
|
| 123 |
echo '<table class="form-table"><tbody>'; |
| 124 |
|
| 125 |
echo '<tr valign="top"> |
| 126 |
<th scope="row"><label for="passwords_check">Password Check</label><a title="This feature is available in the PRO version. Click for details." href="#" data-feature="passwords_check" class="open-upsell pro-label">PRO</a></th> |
| 127 |
<td><button class="button button-primary button-large open-upsell" data-feature="passwords_check" style="margin-bottom:6px;">Test user passwords <i class="loginlockdown-icon loginlockdown-lock"></i></button>'; |
| 128 |
echo '<br><span>Check if any user has a weak password that is vulnerable to common brute-force dictionary attacks.</span>'; |
| 129 |
echo '</td></tr>'; |
| 130 |
|
| 131 |
echo '<tr valign="top"> |
| 132 |
<th scope="row"><label for="anonymous_logging">Anonymous Activity Logging</label><a title="This feature is available in the PRO version. Click for details." href="#" data-feature="anonymous_logging" class="open-upsell pro-label">PRO</a></th> |
| 133 |
<td>'; |
| 134 |
echo '<div class="open-upsell open-upsell-block">'; |
| 135 |
LoginLockdown_Utility::create_toggle_switch('anonymous_logging', array('saved_value' => 0, 'option_key' => '')); |
| 136 |
echo '</div>'; |
| 137 |
echo '<br /><span>Logging anonymously means IP addresses of your visitors are stored as hashed values.</span>'; |
| 138 |
echo '</td></tr>'; |
| 139 |
|
| 140 |
echo '<tr valign="top"> |
| 141 |
<th scope="row"><label for="block_bots">Block Bots</label><a title="This feature is available in the PRO version. Click for details." href="#" data-feature="block_bots" class="open-upsell pro-label">PRO</a></th> |
| 142 |
<td>'; |
| 143 |
echo '<div class="open-upsell open-upsell-block">'; |
| 144 |
LoginLockdown_Utility::create_toggle_switch('block_bots', array('saved_value' => 0, 'option_key' => '')); |
| 145 |
echo '</div>'; |
| 146 |
echo '<br /><span>Block bots from accessing the login page and attempting to log in.</span>'; |
| 147 |
echo '</td></tr>'; |
| 148 |
|
| 149 |
echo '<tr valign="top"> |
| 150 |
<th scope="row"><label for="instant_block_nonusers">Block Login Attempts With Non-existing Usernames</label><a title="This feature is available in the PRO version. Click for details." href="#" data-feature="instant_block_nonusers" class="open-upsell pro-label">PRO</a></th> |
| 151 |
<td>'; |
| 152 |
echo '<div class="open-upsell open-upsell-block">'; |
| 153 |
LoginLockdown_Utility::create_toggle_switch('instant_block_nonusers', array('saved_value' => 0, 'option_key' => '')); |
| 154 |
echo '</div>'; |
| 155 |
echo '<br /><span>Immediately block IP if there is a failed login attempt with a non-existing username</span>'; |
| 156 |
echo '</td></tr>'; |
| 157 |
|
| 158 |
echo '<tr valign="top"> |
| 159 |
<th scope="row"><label for="honeypot">Add Honeypot for Bots</label><a title="This feature is available in the PRO version. Click for details." href="#" data-feature="honeypot" class="open-upsell pro-label">PRO</a></th> |
| 160 |
<td>'; |
| 161 |
echo '<div class="open-upsell open-upsell-block">'; |
| 162 |
LoginLockdown_Utility::create_toggle_switch('honeypot', array('saved_value' => 0, 'option_key' => '')); |
| 163 |
echo '</div>'; |
| 164 |
echo '<br /><span>Add a special, hidden "honeypot" field to the login form to catch and prevent bots from attempting to log in.<br>This does not affect the way humans log in, nor does it add an extra step.</span>'; |
| 165 |
echo '</td></tr>'; |
| 166 |
|
| 167 |
echo '<table class="form-table"><tbody>'; |
| 168 |
|
| 169 |
$cookie_lifetime = array(); |
| 170 |
$cookie_lifetime[] = array('val' => '14', 'label' => '14 days (default)', 'class' => 'pro-option'); |
| 171 |
$cookie_lifetime[] = array('val' => '30', 'label' => '30 days'); |
| 172 |
$cookie_lifetime[] = array('val' => '90', 'label' => '3 months'); |
| 173 |
$cookie_lifetime[] = array('val' => '180', 'label' => '6 months'); |
| 174 |
$cookie_lifetime[] = array('val' => '365', 'label' => '1 year'); |
| 175 |
|
| 176 |
echo '<tr valign="top"> |
| 177 |
<th scope="row"><label for="cookie_lifetime">Cookie Lifetime</label><a title="This feature is available in the PRO version. Click for details." href="#" data-feature="cookie_lifetime" class="open-upsell pro-label">PRO</a></th> |
| 178 |
<td>'; |
| 179 |
echo '<div class="open-upsell open-upsell-block">'; |
| 180 |
echo '<select id="cookie_lifetime" data-feature="cookie_lifetime" class="open-upsell">'; |
| 181 |
LoginLockdown_Utility::create_select_options($cookie_lifetime, '14'); |
| 182 |
echo '</select>'; |
| 183 |
echo '</div>'; |
| 184 |
echo '<br /><span>Cookie lifetime if "Remember Me" option is checked on login form.</span>'; |
| 185 |
echo '</td></tr>'; |
| 186 |
|
| 187 |
echo '<tr valign="top"> |
| 188 |
<th scope="row"><label for="uninstall_delete">Wipe Data on Plugin Delete</label></th> |
| 189 |
<td>'; |
| 190 |
LoginLockdown_Utility::create_toggle_switch('uninstall_delete', array('saved_value' => $options['uninstall_delete'], 'option_key' => LOGINLOCKDOWN_OPTIONS_KEY . '[uninstall_delete]')); |
| 191 |
echo '<br /><span>If enabled, Login Lockdown options, rules and all log tables will be deleted when the plugin is deleted.</span>'; |
| 192 |
echo '</td></tr>'; |
| 193 |
|
| 194 |
echo '<tr><td></td><td>'; |
| 195 |
LoginLockdown_admin::footer_save_button(); |
| 196 |
echo '</td></tr>'; |
| 197 |
|
| 198 |
echo '</tbody></table>'; |
| 199 |
} |
| 200 |
|
| 201 |
static function tab_tools() |
| 202 |
{ |
| 203 |
$options = LoginLockdown_Setup::get_options(); |
| 204 |
|
| 205 |
echo '<table class="form-table"><tbody>'; |
| 206 |
|
| 207 |
echo '<tr valign="top"> |
| 208 |
<th scope="row"><label for="password_check">Email Test</label></th> |
| 209 |
<td><button id="lockdown_send_email" class="button button-primary button-large" style="margin-bottom:6px;">Send test email</button>'; |
| 210 |
echo '<br><span>Send an email to test that you can receive emails from your website.</span>'; |
| 211 |
echo '</td></tr>'; |
| 212 |
|
| 213 |
echo '<tr valign="top"> |
| 214 |
<th scope="row"><label for="lockdown_recovery_url">Recovery URL</label></th> |
| 215 |
<td><button id="lockdown_recovery_url_show" class="button button-primary button-large" style="margin-bottom:6px;">View Recovery URL</button>'; |
| 216 |
echo '<br><span>In case you lock yourself out and need to whitelist your IP address, please save the recovery URL somewhere safe.<br>Do NOT share the recovery URL.</span>'; |
| 217 |
echo '</td></tr>'; |
| 218 |
|
| 219 |
echo '<tr valign="top"> |
| 220 |
<th><label class="open-upsell open-upsell-block" data-feature="import_file">Import Settings</label><a title="This feature is available in the PRO version. Click for details." href="#" data-feature="import_file" class="open-upsell pro-label">PRO</a></th> |
| 221 |
<td>'; |
| 222 |
echo '<div class="open-upsell open-upsell-block" data-feature="import_file">'; |
| 223 |
echo '<input accept="txt" type="file" name="lockdown_import_file" value=""> |
| 224 |
<button name="lockdown_import_file" id="submit" class="button button-primary button-large" value="">Upload</button>'; |
| 225 |
echo '</div>'; |
| 226 |
echo '</td> |
| 227 |
</tr>'; |
| 228 |
|
| 229 |
echo '<tr valign="top"> |
| 230 |
<th><label class="open-upsell open-upsell-block" data-feature="export_file">Export Settings</label><a title="This feature is available in the PRO version. Click for details." href="#" data-feature="export" class="open-upsell pro-label">PRO</a></th> |
| 231 |
<td>'; |
| 232 |
echo '<div class="open-upsell open-upsell-block" data-feature="export">'; |
| 233 |
echo '<a class="button button-primary button-large" style="padding-top: 3px;" href="#">Download Export File</a>'; |
| 234 |
echo '</div>'; |
| 235 |
echo '</td> |
| 236 |
</tr>'; |
| 237 |
echo '</tbody></table>'; |
| 238 |
} |
| 239 |
} // class LoginLockdown_Tab_Login_Form |
| 240 |
|