Version Description
- Debug information has been added for better support.
Download this release
Release Info
Developer | wpchefgadget |
Plugin | Limit Login Attempts Reloaded |
Version | 2.10.0 |
Comparing to | |
See all releases |
Code changes from version 2.9.0 to 2.10.0
- limit-login-attempts-reloaded.php +1 -1
- readme.txt +5 -2
- views/options-page.php +14 -259
- views/tab-debug.php +38 -0
- views/tab-settings.php +267 -0
limit-login-attempts-reloaded.php
CHANGED
@@ -5,7 +5,7 @@ Description: Limit the rate of login attempts, including by way of cookies and f
|
|
5 |
Author: WPChef
|
6 |
Author URI: https://wpchef.org
|
7 |
Text Domain: limit-login-attempts-reloaded
|
8 |
-
Version: 2.
|
9 |
|
10 |
Copyright 2008 - 2012 Johan Eenfeldt, 2016 - 2019 WPChef
|
11 |
*/
|
5 |
Author: WPChef
|
6 |
Author URI: https://wpchef.org
|
7 |
Text Domain: limit-login-attempts-reloaded
|
8 |
+
Version: 2.10.0
|
9 |
|
10 |
Copyright 2008 - 2012 Johan Eenfeldt, 2016 - 2019 WPChef
|
11 |
*/
|
readme.txt
CHANGED
@@ -2,8 +2,8 @@
|
|
2 |
Contributors: wpchefgadget
|
3 |
Tags: brute force, login, security, GDPR, protection
|
4 |
Requires at least: 3.0
|
5 |
-
Tested up to: 5.
|
6 |
-
Stable tag: 2.
|
7 |
|
8 |
Reloaded version of the original Limit Login Attempts plugin for Login Protection by a team of WordPress developers. GDPR compliant.
|
9 |
|
@@ -51,6 +51,9 @@ Based on the original code from Limit Login Attemps plugin by Johan Eenfeldt.
|
|
51 |
|
52 |
== Changelog ==
|
53 |
|
|
|
|
|
|
|
54 |
= 2.9.0 =
|
55 |
* Trusted IP origins option has been added.
|
56 |
|
2 |
Contributors: wpchefgadget
|
3 |
Tags: brute force, login, security, GDPR, protection
|
4 |
Requires at least: 3.0
|
5 |
+
Tested up to: 5.3
|
6 |
+
Stable tag: 2.10.0
|
7 |
|
8 |
Reloaded version of the original Limit Login Attempts plugin for Login Protection by a team of WordPress developers. GDPR compliant.
|
9 |
|
51 |
|
52 |
== Changelog ==
|
53 |
|
54 |
+
= 2.10.0 =
|
55 |
+
* Debug information has been added for better support.
|
56 |
+
|
57 |
= 2.9.0 =
|
58 |
* Trusted IP origins option has been added.
|
59 |
|
views/options-page.php
CHANGED
@@ -1,269 +1,24 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
if( !defined( 'ABSPATH' ) )
|
4 |
-
exit();
|
5 |
|
6 |
-
|
7 |
-
|
8 |
-
*/
|
9 |
-
|
10 |
-
$gdpr = $this->get_option( 'gdpr', 0 );
|
11 |
-
|
12 |
-
$lockouts_total = $this->get_option( 'lockouts_total', 0 );
|
13 |
-
$lockouts = $this->get_option( 'login_lockouts' );
|
14 |
-
$lockouts_now = is_array( $lockouts ) ? count( $lockouts ) : 0;
|
15 |
-
|
16 |
-
$v = explode( ',', $this->get_option( 'lockout_notify' ) );
|
17 |
-
$log_checked = in_array( 'log', $v ) ? ' checked ' : '';
|
18 |
-
$email_checked = in_array( 'email', $v ) ? ' checked ' : '';
|
19 |
-
|
20 |
-
$white_list_ips = $this->get_option( 'whitelist' );
|
21 |
-
$white_list_ips = ( is_array( $white_list_ips ) && !empty( $white_list_ips ) ) ? implode( "\n", $white_list_ips ) : '';
|
22 |
-
|
23 |
-
$white_list_usernames = $this->get_option( 'whitelist_usernames' );
|
24 |
-
$white_list_usernames = ( is_array( $white_list_usernames ) && !empty( $white_list_usernames ) ) ? implode( "\n", $white_list_usernames ) : '';
|
25 |
-
|
26 |
-
$black_list_ips = $this->get_option( 'blacklist' );
|
27 |
-
$black_list_ips = ( is_array( $black_list_ips ) && !empty( $black_list_ips ) ) ? implode( "\n", $black_list_ips ) : '';
|
28 |
-
|
29 |
-
$black_list_usernames = $this->get_option( 'blacklist_usernames' );
|
30 |
-
$black_list_usernames = ( is_array( $black_list_usernames ) && !empty( $black_list_usernames ) ) ? implode( "\n", $black_list_usernames ) : '';
|
31 |
-
|
32 |
-
$admin_notify_email = $this->get_option( 'admin_notify_email' );
|
33 |
-
$admin_email_placeholder = (!is_multisite()) ? get_option( 'admin_email' ) : get_site_option( 'admin_email' );
|
34 |
-
|
35 |
-
$trusted_ip_origins = $this->get_option( 'trusted_ip_origins' );
|
36 |
-
$trusted_ip_origins = ( is_array( $trusted_ip_origins ) && !empty( $trusted_ip_origins ) ) ? implode( ", ", $trusted_ip_origins ) : 'REMOTE_ADDR';
|
37 |
|
|
|
|
|
|
|
|
|
38 |
?>
|
|
|
39 |
<div class="wrap limit-login-page-settings">
|
40 |
<h2><?php echo __( 'Limit Login Attempts Settings', 'limit-login-attempts-reloaded' ); ?></h2>
|
41 |
-
<h3><?php echo __( 'Statistics', 'limit-login-attempts-reloaded' ); ?></h3>
|
42 |
-
<form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
|
43 |
-
<?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
|
44 |
-
<table class="form-table">
|
45 |
-
<tr>
|
46 |
-
<th scope="row" valign="top"><?php echo __( 'Total lockouts', 'limit-login-attempts-reloaded' ); ?></th>
|
47 |
-
<td>
|
48 |
-
<?php if( $lockouts_total > 0 ) { ?>
|
49 |
-
<input class="button" name="reset_total"
|
50 |
-
value="<?php echo __( 'Reset Counter', 'limit-login-attempts-reloaded' ); ?>"
|
51 |
-
type="submit"/>
|
52 |
-
<?php echo sprintf( _n( '%d lockout since last reset', '%d lockouts since last reset', $lockouts_total, 'limit-login-attempts-reloaded' ), $lockouts_total ); ?>
|
53 |
-
<?php } else {
|
54 |
-
echo __( 'No lockouts yet', 'limit-login-attempts-reloaded' );
|
55 |
-
} ?>
|
56 |
-
</td>
|
57 |
-
</tr>
|
58 |
-
<?php if( $lockouts_now > 0 ) { ?>
|
59 |
-
<tr>
|
60 |
-
<th scope="row"
|
61 |
-
valign="top"><?php echo __( 'Active lockouts', 'limit-login-attempts-reloaded' ); ?></th>
|
62 |
-
<td>
|
63 |
-
<input class="button" name="reset_current"
|
64 |
-
value="<?php echo __( 'Restore Lockouts', 'limit-login-attempts-reloaded' ); ?>"
|
65 |
-
type="submit"/>
|
66 |
-
<?php echo sprintf( __( '%d IP is currently blocked from trying to log in', 'limit-login-attempts-reloaded' ), $lockouts_now ); ?>
|
67 |
-
</td>
|
68 |
-
</tr>
|
69 |
-
<?php } ?>
|
70 |
-
</table>
|
71 |
-
</form>
|
72 |
-
<h3><?php echo __( 'Options', 'limit-login-attempts-reloaded' ); ?></h3>
|
73 |
-
<form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
|
74 |
-
<?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
|
75 |
-
<?php if ( is_network_admin() ): ?>
|
76 |
-
<input type="checkbox" name="allow_local_options" <?php echo $this->get_option( 'allow_local_options' ) ? 'checked' : '' ?> value="1"/> <?php esc_html_e( 'Let network sites use their own settings', 'limit-login-attempts-reloaded' ); ?>
|
77 |
-
<p class="description"><?php esc_html_e('If disabled, the global settings will be forcibly applied to the entire network.') ?></p>
|
78 |
-
<?php elseif ( $this->network_mode ): ?>
|
79 |
-
<input type="checkbox" name="use_global_options" <?php echo $this->get_option('use_local_options' ) ? '' : 'checked' ?> value="1" class="use_global_options"/> <?php echo __( 'Use global settings', 'limit-login-attempts-reloaded' ); ?><br/>
|
80 |
-
<script>
|
81 |
-
jQuery(function($){
|
82 |
-
var first = true;
|
83 |
-
$('.use_global_options').change( function(){
|
84 |
-
var form = $(this).siblings('table');
|
85 |
-
form.stop();
|
86 |
-
|
87 |
-
if ( this.checked )
|
88 |
-
first ? form.hide() : form.fadeOut();
|
89 |
-
else
|
90 |
-
first ? form.show() : form.fadeIn();
|
91 |
-
|
92 |
-
first = false;
|
93 |
-
}).change();
|
94 |
-
});
|
95 |
-
</script>
|
96 |
-
<?php endif ?>
|
97 |
-
<table class="form-table">
|
98 |
-
<tr>
|
99 |
-
<th scope="row"
|
100 |
-
valign="top"><?php echo __( 'GDPR compliance', 'limit-login-attempts-reloaded' ); ?></th>
|
101 |
-
<td>
|
102 |
-
<input type="checkbox" name="gdpr" value="1" <?php if($gdpr): ?> checked <?php endif; ?>/>
|
103 |
-
<?php echo __( 'this makes the plugin <a href="https://gdpr-info.eu/" target="_blank" >GDPR</a> compliant', 'limit-login-attempts-reloaded' ); ?> <br/>
|
104 |
-
</td>
|
105 |
-
</tr>
|
106 |
-
<tr>
|
107 |
-
<th scope="row" valign="top"><?php echo __( 'Lockout', 'limit-login-attempts-reloaded' ); ?></th>
|
108 |
-
<td>
|
109 |
-
|
110 |
-
<input type="text" size="3" maxlength="4"
|
111 |
-
value="<?php echo( $this->get_option( 'allowed_retries' ) ); ?>"
|
112 |
-
name="allowed_retries"/> <?php echo __( 'allowed retries', 'limit-login-attempts-reloaded' ); ?>
|
113 |
-
<br/>
|
114 |
-
<input type="text" size="3" maxlength="4"
|
115 |
-
value="<?php echo( $this->get_option( 'lockout_duration' ) / 60 ); ?>"
|
116 |
-
name="lockout_duration"/> <?php echo __( 'minutes lockout', 'limit-login-attempts-reloaded' ); ?>
|
117 |
-
<br/>
|
118 |
-
<input type="text" size="3" maxlength="4"
|
119 |
-
value="<?php echo( $this->get_option( 'allowed_lockouts' ) ); ?>"
|
120 |
-
name="allowed_lockouts"/> <?php echo __( 'lockouts increase lockout time to', 'limit-login-attempts-reloaded' ); ?>
|
121 |
-
<input type="text" size="3" maxlength="4"
|
122 |
-
value="<?php echo( $this->get_option( 'long_duration' ) / 3600 ); ?>"
|
123 |
-
name="long_duration"/> <?php echo __( 'hours', 'limit-login-attempts-reloaded' ); ?> <br/>
|
124 |
-
<input type="text" size="3" maxlength="4"
|
125 |
-
value="<?php echo( $this->get_option( 'valid_duration' ) / 3600 ); ?>"
|
126 |
-
name="valid_duration"/> <?php echo __( 'hours until retries are reset', 'limit-login-attempts-reloaded' ); ?>
|
127 |
-
</td>
|
128 |
-
</tr>
|
129 |
-
<tr>
|
130 |
-
<th scope="row"
|
131 |
-
valign="top"><?php echo __( 'Notify on lockout', 'limit-login-attempts-reloaded' ); ?></th>
|
132 |
-
<td>
|
133 |
-
<input type="checkbox" name="lockout_notify_log" <?php echo $log_checked; ?>
|
134 |
-
value="log"/> <?php echo __( 'Lockout log', 'limit-login-attempts-reloaded' ); ?><br/>
|
135 |
-
<input type="checkbox" name="lockout_notify_email" <?php echo $email_checked; ?>
|
136 |
-
value="email"/> <?php echo __( 'Email to', 'limit-login-attempts-reloaded' ); ?>
|
137 |
-
<input type="email" name="admin_notify_email"
|
138 |
-
value="<?php echo esc_attr( $admin_notify_email ) ?>"
|
139 |
-
placeholder="<?php echo esc_attr( $admin_email_placeholder ); ?>"/> <?php echo __( 'after', 'limit-login-attempts-reloaded' ); ?>
|
140 |
-
<input type="text" size="3" maxlength="4"
|
141 |
-
value="<?php echo( $this->get_option( 'notify_email_after' ) ); ?>"
|
142 |
-
name="email_after"/> <?php echo __( 'lockouts', 'limit-login-attempts-reloaded' ); ?>
|
143 |
-
</td>
|
144 |
-
</tr>
|
145 |
-
<tr>
|
146 |
-
<th scope="row"
|
147 |
-
valign="top"><?php echo __( 'Whitelist', 'limit-login-attempts-reloaded' ); ?></th>
|
148 |
-
<td>
|
149 |
-
<div class="field-col">
|
150 |
-
<p class="description"><?php _e( 'One IP or IP range (1.2.3.4-5.6.7.8) per line', 'limit-login-attempts-reloaded' ); ?></p>
|
151 |
-
<textarea name="lla_whitelist_ips" rows="10" cols="50"><?php echo esc_textarea( $white_list_ips ); ?></textarea>
|
152 |
-
</div>
|
153 |
-
<div class="field-col">
|
154 |
-
<p class="description"><?php _e( 'One Username per line', 'limit-login-attempts-reloaded' ); ?></p>
|
155 |
-
<textarea name="lla_whitelist_usernames" rows="10" cols="50"><?php echo esc_textarea( $white_list_usernames ); ?></textarea>
|
156 |
-
</div>
|
157 |
-
</td>
|
158 |
-
</tr>
|
159 |
-
<tr>
|
160 |
-
<th scope="row"
|
161 |
-
valign="top"><?php echo __( 'Blacklist', 'limit-login-attempts-reloaded' ); ?></th>
|
162 |
-
<td>
|
163 |
-
<div class="field-col">
|
164 |
-
<p class="description"><?php _e( 'One IP or IP range (1.2.3.4-5.6.7.8) per line', 'limit-login-attempts-reloaded' ); ?></p>
|
165 |
-
<textarea name="lla_blacklist_ips" rows="10" cols="50"><?php echo esc_textarea( $black_list_ips ); ?></textarea>
|
166 |
-
</div>
|
167 |
-
<div class="field-col">
|
168 |
-
<p class="description"><?php _e( 'One Username per line', 'limit-login-attempts-reloaded' ); ?></p>
|
169 |
-
<textarea name="lla_blacklist_usernames" rows="10" cols="50"><?php echo esc_textarea( $black_list_usernames ); ?></textarea>
|
170 |
-
</div>
|
171 |
-
</td>
|
172 |
-
</tr>
|
173 |
-
<tr>
|
174 |
-
<th scope="row"
|
175 |
-
valign="top"><?php echo __( 'Trusted IP Origins', 'limit-login-attempts-reloaded' ); ?></th>
|
176 |
-
<td>
|
177 |
-
<div class="field-col">
|
178 |
-
<input type="text" class="regular-text" style="width: 100%;max-width: 431px;" name="lla_trusted_ip_origins" value="<?php echo esc_attr( $trusted_ip_origins ); ?>">
|
179 |
-
<p class="description"><?php _e( 'Specify the origins you trust in order of priority, separated by commas. We strongly recommend that you <b>do not</b> use anything other than REMOTE_ADDR since other origins can be easily faked. Examples: HTTP_X_FORWARDED_FOR, HTTP_CF_CONNECTING_IP, HTTP_X_SUCURI_CLIENTIP', 'limit-login-attempts-reloaded' ); ?></p>
|
180 |
-
</div>
|
181 |
-
</td>
|
182 |
-
</tr>
|
183 |
-
</table>
|
184 |
-
<p class="submit">
|
185 |
-
<input class="button button-primary" name="update_options" value="<?php echo __( 'Save Options', 'limit-login-attempts-reloaded' ); ?>"
|
186 |
-
type="submit"/>
|
187 |
-
</p>
|
188 |
-
</form>
|
189 |
-
<?php
|
190 |
-
$log = $this->get_option( 'logged' );
|
191 |
-
$log = LLA_Helpers::sorted_log_by_date( $log );
|
192 |
-
|
193 |
-
$lockouts = (array)$this->get_option('lockouts');
|
194 |
-
|
195 |
-
if( is_array( $log ) && ! empty( $log ) ) { ?>
|
196 |
-
<h3><?php echo __( 'Lockout log', 'limit-login-attempts-reloaded' ); ?></h3>
|
197 |
-
<form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
|
198 |
-
<?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
|
199 |
-
<input type="hidden" value="true" name="clear_log"/>
|
200 |
-
<p class="submit">
|
201 |
-
<input class="button" name="submit" value="<?php echo __( 'Clear Log', 'limit-login-attempts-reloaded' ); ?>"
|
202 |
-
type="submit"/>
|
203 |
-
</p>
|
204 |
-
</form>
|
205 |
-
|
206 |
-
<div class="limit-login-log">
|
207 |
-
<table class="form-table">
|
208 |
-
<tr>
|
209 |
-
<th scope="col"><?php _e( "Date", 'limit-login-attempts-reloaded' ); ?></th>
|
210 |
-
<th scope="col"><?php echo _x( "IP", "Internet address", 'limit-login-attempts-reloaded' ); ?></th>
|
211 |
-
<th scope="col"><?php _e( 'Tried to log in as', 'limit-login-attempts-reloaded' ); ?></th>
|
212 |
-
<th scope="col"><?php _e( 'Gateway', 'limit-login-attempts-reloaded' ); ?></th>
|
213 |
-
<th>
|
214 |
-
</tr>
|
215 |
-
|
216 |
-
<?php foreach ( $log as $date => $user_info ) : ?>
|
217 |
-
<tr>
|
218 |
-
<td class="limit-login-date"><?php echo date_i18n( 'F d, Y H:i', $date ); ?></td>
|
219 |
-
<td class="limit-login-ip">
|
220 |
-
<?php echo esc_html( $user_info['ip'] ); ?>
|
221 |
-
</td>
|
222 |
-
<td class="limit-login-max"><?php echo esc_html( $user_info['username'] ) . ' (' . esc_html( $user_info['counter'] ) .' lockouts)'; ?></td>
|
223 |
-
<td class="limit-login-gateway"><?php echo esc_html( $user_info['gateway'] ); ?></td>
|
224 |
-
<td>
|
225 |
-
<?php if ( !empty( $lockouts[ $user_info['ip'] ] ) && $lockouts[ $user_info['ip'] ] > time() ) : ?>
|
226 |
-
<a href="#" class="button limit-login-unlock" data-ip="<?=esc_attr($user_info['ip'])?>" data-username="<?=esc_attr($user_info['username'])?>">Unlock</a>
|
227 |
-
<?php elseif ( $user_info['unlocked'] ): ?>
|
228 |
-
Unlocked
|
229 |
-
<?php endif ?>
|
230 |
-
</tr>
|
231 |
-
<?php endforeach; ?>
|
232 |
-
|
233 |
-
</table>
|
234 |
-
</div>
|
235 |
-
<script>jQuery( function($) {
|
236 |
-
$('.limit-login-log .limit-login-unlock').click( function()
|
237 |
-
{
|
238 |
-
var btn = $(this);
|
239 |
-
|
240 |
-
if ( btn.hasClass('disabled') )
|
241 |
-
return false;
|
242 |
-
btn.addClass( 'disabled' );
|
243 |
-
|
244 |
-
$.post( ajaxurl, {
|
245 |
-
action: 'limit-login-unlock',
|
246 |
-
sec: '<?=wp_create_nonce('limit-login-unlock') ?>',
|
247 |
-
ip: btn.data('ip'),
|
248 |
-
username: btn.data('username')
|
249 |
-
} )
|
250 |
-
.done( function(data) {
|
251 |
-
if ( data === true )
|
252 |
-
btn.fadeOut( function(){ $(this).parent().text('Unlocked') });
|
253 |
-
else
|
254 |
-
fail();
|
255 |
-
}).fail( fail );
|
256 |
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
|
262 |
-
|
263 |
-
|
264 |
-
} )</script>
|
265 |
-
<?php
|
266 |
-
} /* if showing $log */
|
267 |
-
?>
|
268 |
|
269 |
-
</div>
|
1 |
<?php
|
2 |
|
3 |
+
if( !defined( 'ABSPATH' ) ) exit();
|
|
|
4 |
|
5 |
+
$active_tab = "settings";
|
6 |
+
if(isset($_GET["tab"])) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
+
if($_GET["tab"] === "debug") {
|
9 |
+
$active_tab = "debug";
|
10 |
+
}
|
11 |
+
}
|
12 |
?>
|
13 |
+
|
14 |
<div class="wrap limit-login-page-settings">
|
15 |
<h2><?php echo __( 'Limit Login Attempts Settings', 'limit-login-attempts-reloaded' ); ?></h2>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
+
<h2 class="nav-tab-wrapper">
|
18 |
+
<a href="<?php echo $this->get_options_page_uri(); ?>&tab=settings" class="nav-tab <?php if($active_tab == 'settings'){echo 'nav-tab-active';} ?> "><?php _e('Settings', 'limit-login-attempts-reloaded'); ?></a>
|
19 |
+
<a href="<?php echo $this->get_options_page_uri(); ?>&tab=debug" class="nav-tab <?php if($active_tab == 'debug'){echo 'nav-tab-active';} ?>"><?php _e('Debug', 'limit-login-attempts-reloaded'); ?></a>
|
20 |
+
</h2>
|
21 |
|
22 |
+
<?php include_once(LLA_PLUGIN_DIR.'views/tab-'.$active_tab.'.php'); ?>
|
23 |
+
</div>
|
|
|
|
|
|
|
|
|
24 |
|
|
views/tab-debug.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( !defined( 'ABSPATH' ) ) exit();
|
4 |
+
|
5 |
+
$debug_info = '';
|
6 |
+
|
7 |
+
$ips = $server = [];
|
8 |
+
foreach ($_SERVER as $key => $value) {
|
9 |
+
|
10 |
+
if(in_array($key, ['SERVER_ADDR'])) continue;
|
11 |
+
|
12 |
+
if(filter_var($value, FILTER_VALIDATE_IP)) {
|
13 |
+
|
14 |
+
if(!in_array($value, $ips)) {
|
15 |
+
|
16 |
+
$ips[] = $value;
|
17 |
+
}
|
18 |
+
|
19 |
+
if(in_array($value, ['127.0.0.1', '0.0.0.0']))
|
20 |
+
$server[$key] = $value;
|
21 |
+
else
|
22 |
+
$server[$key] = 'IP'.array_search($value, $ips);
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
foreach ($server as $server_key => $ip ) {
|
27 |
+
$debug_info .= $server_key . ' = ' . $ip . "\n";
|
28 |
+
}
|
29 |
+
?>
|
30 |
+
|
31 |
+
<table class="form-table">
|
32 |
+
<tr>
|
33 |
+
<th scope="row" valign="top"><?php echo __( 'Debug info', 'limit-login-attempts-reloaded' ); ?></th>
|
34 |
+
<td>
|
35 |
+
<textarea cols="70" rows="10" onclick="this.select()" readonly><?php echo esc_textarea($debug_info); ?></textarea>
|
36 |
+
</td>
|
37 |
+
</tr>
|
38 |
+
</table>
|
views/tab-settings.php
ADDED
@@ -0,0 +1,267 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( !defined( 'ABSPATH' ) ) exit();
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var $this Limit_Login_Attempts
|
7 |
+
*/
|
8 |
+
|
9 |
+
$gdpr = $this->get_option( 'gdpr', 0 );
|
10 |
+
|
11 |
+
$lockouts_total = $this->get_option( 'lockouts_total', 0 );
|
12 |
+
$lockouts = $this->get_option( 'login_lockouts' );
|
13 |
+
$lockouts_now = is_array( $lockouts ) ? count( $lockouts ) : 0;
|
14 |
+
|
15 |
+
$v = explode( ',', $this->get_option( 'lockout_notify' ) );
|
16 |
+
$log_checked = in_array( 'log', $v ) ? ' checked ' : '';
|
17 |
+
$email_checked = in_array( 'email', $v ) ? ' checked ' : '';
|
18 |
+
|
19 |
+
$white_list_ips = $this->get_option( 'whitelist' );
|
20 |
+
$white_list_ips = ( is_array( $white_list_ips ) && !empty( $white_list_ips ) ) ? implode( "\n", $white_list_ips ) : '';
|
21 |
+
|
22 |
+
$white_list_usernames = $this->get_option( 'whitelist_usernames' );
|
23 |
+
$white_list_usernames = ( is_array( $white_list_usernames ) && !empty( $white_list_usernames ) ) ? implode( "\n", $white_list_usernames ) : '';
|
24 |
+
|
25 |
+
$black_list_ips = $this->get_option( 'blacklist' );
|
26 |
+
$black_list_ips = ( is_array( $black_list_ips ) && !empty( $black_list_ips ) ) ? implode( "\n", $black_list_ips ) : '';
|
27 |
+
|
28 |
+
$black_list_usernames = $this->get_option( 'blacklist_usernames' );
|
29 |
+
$black_list_usernames = ( is_array( $black_list_usernames ) && !empty( $black_list_usernames ) ) ? implode( "\n", $black_list_usernames ) : '';
|
30 |
+
|
31 |
+
$admin_notify_email = $this->get_option( 'admin_notify_email' );
|
32 |
+
$admin_email_placeholder = (!is_multisite()) ? get_option( 'admin_email' ) : get_site_option( 'admin_email' );
|
33 |
+
|
34 |
+
$trusted_ip_origins = $this->get_option( 'trusted_ip_origins' );
|
35 |
+
$trusted_ip_origins = ( is_array( $trusted_ip_origins ) && !empty( $trusted_ip_origins ) ) ? implode( ", ", $trusted_ip_origins ) : 'REMOTE_ADDR';
|
36 |
+
|
37 |
+
|
38 |
+
?>
|
39 |
+
|
40 |
+
<h3><?php echo __( 'Statistics', 'limit-login-attempts-reloaded' ); ?></h3>
|
41 |
+
<form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
|
42 |
+
<?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
|
43 |
+
<table class="form-table">
|
44 |
+
<tr>
|
45 |
+
<th scope="row" valign="top"><?php echo __( 'Total lockouts', 'limit-login-attempts-reloaded' ); ?></th>
|
46 |
+
<td>
|
47 |
+
<?php if( $lockouts_total > 0 ) { ?>
|
48 |
+
<input class="button" name="reset_total"
|
49 |
+
value="<?php echo __( 'Reset Counter', 'limit-login-attempts-reloaded' ); ?>"
|
50 |
+
type="submit"/>
|
51 |
+
<?php echo sprintf( _n( '%d lockout since last reset', '%d lockouts since last reset', $lockouts_total, 'limit-login-attempts-reloaded' ), $lockouts_total ); ?>
|
52 |
+
<?php } else {
|
53 |
+
echo __( 'No lockouts yet', 'limit-login-attempts-reloaded' );
|
54 |
+
} ?>
|
55 |
+
</td>
|
56 |
+
</tr>
|
57 |
+
<?php if( $lockouts_now > 0 ) { ?>
|
58 |
+
<tr>
|
59 |
+
<th scope="row"
|
60 |
+
valign="top"><?php echo __( 'Active lockouts', 'limit-login-attempts-reloaded' ); ?></th>
|
61 |
+
<td>
|
62 |
+
<input class="button" name="reset_current"
|
63 |
+
value="<?php echo __( 'Restore Lockouts', 'limit-login-attempts-reloaded' ); ?>"
|
64 |
+
type="submit"/>
|
65 |
+
<?php echo sprintf( __( '%d IP is currently blocked from trying to log in', 'limit-login-attempts-reloaded' ), $lockouts_now ); ?>
|
66 |
+
</td>
|
67 |
+
</tr>
|
68 |
+
<?php } ?>
|
69 |
+
</table>
|
70 |
+
</form>
|
71 |
+
<h3><?php echo __( 'Options', 'limit-login-attempts-reloaded' ); ?></h3>
|
72 |
+
<form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
|
73 |
+
<?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
|
74 |
+
<?php if ( is_network_admin() ): ?>
|
75 |
+
<input type="checkbox" name="allow_local_options" <?php echo $this->get_option( 'allow_local_options' ) ? 'checked' : '' ?> value="1"/> <?php esc_html_e( 'Let network sites use their own settings', 'limit-login-attempts-reloaded' ); ?>
|
76 |
+
<p class="description"><?php esc_html_e('If disabled, the global settings will be forcibly applied to the entire network.') ?></p>
|
77 |
+
<?php elseif ( $this->network_mode ): ?>
|
78 |
+
<input type="checkbox" name="use_global_options" <?php echo $this->get_option('use_local_options' ) ? '' : 'checked' ?> value="1" class="use_global_options"/> <?php echo __( 'Use global settings', 'limit-login-attempts-reloaded' ); ?><br/>
|
79 |
+
<script>
|
80 |
+
jQuery(function($){
|
81 |
+
var first = true;
|
82 |
+
$('.use_global_options').change( function(){
|
83 |
+
var form = $(this).siblings('table');
|
84 |
+
form.stop();
|
85 |
+
|
86 |
+
if ( this.checked )
|
87 |
+
first ? form.hide() : form.fadeOut();
|
88 |
+
else
|
89 |
+
first ? form.show() : form.fadeIn();
|
90 |
+
|
91 |
+
first = false;
|
92 |
+
}).change();
|
93 |
+
});
|
94 |
+
</script>
|
95 |
+
<?php endif ?>
|
96 |
+
<table class="form-table">
|
97 |
+
<tr>
|
98 |
+
<th scope="row"
|
99 |
+
valign="top"><?php echo __( 'GDPR compliance', 'limit-login-attempts-reloaded' ); ?></th>
|
100 |
+
<td>
|
101 |
+
<input type="checkbox" name="gdpr" value="1" <?php if($gdpr): ?> checked <?php endif; ?>/>
|
102 |
+
<?php echo __( 'this makes the plugin <a href="https://gdpr-info.eu/" target="_blank" >GDPR</a> compliant', 'limit-login-attempts-reloaded' ); ?> <br/>
|
103 |
+
</td>
|
104 |
+
</tr>
|
105 |
+
<tr>
|
106 |
+
<th scope="row" valign="top"><?php echo __( 'Lockout', 'limit-login-attempts-reloaded' ); ?></th>
|
107 |
+
<td>
|
108 |
+
|
109 |
+
<input type="text" size="3" maxlength="4"
|
110 |
+
value="<?php echo( $this->get_option( 'allowed_retries' ) ); ?>"
|
111 |
+
name="allowed_retries"/> <?php echo __( 'allowed retries', 'limit-login-attempts-reloaded' ); ?>
|
112 |
+
<br/>
|
113 |
+
<input type="text" size="3" maxlength="4"
|
114 |
+
value="<?php echo( $this->get_option( 'lockout_duration' ) / 60 ); ?>"
|
115 |
+
name="lockout_duration"/> <?php echo __( 'minutes lockout', 'limit-login-attempts-reloaded' ); ?>
|
116 |
+
<br/>
|
117 |
+
<input type="text" size="3" maxlength="4"
|
118 |
+
value="<?php echo( $this->get_option( 'allowed_lockouts' ) ); ?>"
|
119 |
+
name="allowed_lockouts"/> <?php echo __( 'lockouts increase lockout time to', 'limit-login-attempts-reloaded' ); ?>
|
120 |
+
<input type="text" size="3" maxlength="4"
|
121 |
+
value="<?php echo( $this->get_option( 'long_duration' ) / 3600 ); ?>"
|
122 |
+
name="long_duration"/> <?php echo __( 'hours', 'limit-login-attempts-reloaded' ); ?> <br/>
|
123 |
+
<input type="text" size="3" maxlength="4"
|
124 |
+
value="<?php echo( $this->get_option( 'valid_duration' ) / 3600 ); ?>"
|
125 |
+
name="valid_duration"/> <?php echo __( 'hours until retries are reset', 'limit-login-attempts-reloaded' ); ?>
|
126 |
+
</td>
|
127 |
+
</tr>
|
128 |
+
<tr>
|
129 |
+
<th scope="row"
|
130 |
+
valign="top"><?php echo __( 'Notify on lockout', 'limit-login-attempts-reloaded' ); ?></th>
|
131 |
+
<td>
|
132 |
+
<input type="checkbox" name="lockout_notify_log" <?php echo $log_checked; ?>
|
133 |
+
value="log"/> <?php echo __( 'Lockout log', 'limit-login-attempts-reloaded' ); ?><br/>
|
134 |
+
<input type="checkbox" name="lockout_notify_email" <?php echo $email_checked; ?>
|
135 |
+
value="email"/> <?php echo __( 'Email to', 'limit-login-attempts-reloaded' ); ?>
|
136 |
+
<input type="email" name="admin_notify_email"
|
137 |
+
value="<?php echo esc_attr( $admin_notify_email ) ?>"
|
138 |
+
placeholder="<?php echo esc_attr( $admin_email_placeholder ); ?>"/> <?php echo __( 'after', 'limit-login-attempts-reloaded' ); ?>
|
139 |
+
<input type="text" size="3" maxlength="4"
|
140 |
+
value="<?php echo( $this->get_option( 'notify_email_after' ) ); ?>"
|
141 |
+
name="email_after"/> <?php echo __( 'lockouts', 'limit-login-attempts-reloaded' ); ?>
|
142 |
+
</td>
|
143 |
+
</tr>
|
144 |
+
<tr>
|
145 |
+
<th scope="row"
|
146 |
+
valign="top"><?php echo __( 'Whitelist', 'limit-login-attempts-reloaded' ); ?></th>
|
147 |
+
<td>
|
148 |
+
<div class="field-col">
|
149 |
+
<p class="description"><?php _e( 'One IP or IP range (1.2.3.4-5.6.7.8) per line', 'limit-login-attempts-reloaded' ); ?></p>
|
150 |
+
<textarea name="lla_whitelist_ips" rows="10" cols="50"><?php echo esc_textarea( $white_list_ips ); ?></textarea>
|
151 |
+
</div>
|
152 |
+
<div class="field-col">
|
153 |
+
<p class="description"><?php _e( 'One Username per line', 'limit-login-attempts-reloaded' ); ?></p>
|
154 |
+
<textarea name="lla_whitelist_usernames" rows="10" cols="50"><?php echo esc_textarea( $white_list_usernames ); ?></textarea>
|
155 |
+
</div>
|
156 |
+
</td>
|
157 |
+
</tr>
|
158 |
+
<tr>
|
159 |
+
<th scope="row"
|
160 |
+
valign="top"><?php echo __( 'Blacklist', 'limit-login-attempts-reloaded' ); ?></th>
|
161 |
+
<td>
|
162 |
+
<div class="field-col">
|
163 |
+
<p class="description"><?php _e( 'One IP or IP range (1.2.3.4-5.6.7.8) per line', 'limit-login-attempts-reloaded' ); ?></p>
|
164 |
+
<textarea name="lla_blacklist_ips" rows="10" cols="50"><?php echo esc_textarea( $black_list_ips ); ?></textarea>
|
165 |
+
</div>
|
166 |
+
<div class="field-col">
|
167 |
+
<p class="description"><?php _e( 'One Username per line', 'limit-login-attempts-reloaded' ); ?></p>
|
168 |
+
<textarea name="lla_blacklist_usernames" rows="10" cols="50"><?php echo esc_textarea( $black_list_usernames ); ?></textarea>
|
169 |
+
</div>
|
170 |
+
</td>
|
171 |
+
</tr>
|
172 |
+
<tr>
|
173 |
+
<th scope="row"
|
174 |
+
valign="top"><?php echo __( 'Trusted IP Origins', 'limit-login-attempts-reloaded' ); ?></th>
|
175 |
+
<td>
|
176 |
+
<div class="field-col">
|
177 |
+
<input type="text" class="regular-text" style="width: 100%;max-width: 431px;" name="lla_trusted_ip_origins" value="<?php echo esc_attr( $trusted_ip_origins ); ?>">
|
178 |
+
<p class="description"><?php _e( 'Specify the origins you trust in order of priority, separated by commas. We strongly recommend that you <b>do not</b> use anything other than REMOTE_ADDR since other origins can be easily faked. Examples: HTTP_X_FORWARDED_FOR, HTTP_CF_CONNECTING_IP, HTTP_X_SUCURI_CLIENTIP', 'limit-login-attempts-reloaded' ); ?></p>
|
179 |
+
</div>
|
180 |
+
</td>
|
181 |
+
</tr>
|
182 |
+
</table>
|
183 |
+
<p class="submit">
|
184 |
+
<input class="button button-primary" name="update_options" value="<?php echo __( 'Save Options', 'limit-login-attempts-reloaded' ); ?>"
|
185 |
+
type="submit"/>
|
186 |
+
</p>
|
187 |
+
</form>
|
188 |
+
<?php
|
189 |
+
$log = $this->get_option( 'logged' );
|
190 |
+
$log = LLA_Helpers::sorted_log_by_date( $log );
|
191 |
+
|
192 |
+
$lockouts = (array)$this->get_option('lockouts');
|
193 |
+
|
194 |
+
if( is_array( $log ) && ! empty( $log ) ) { ?>
|
195 |
+
<h3><?php echo __( 'Lockout log', 'limit-login-attempts-reloaded' ); ?></h3>
|
196 |
+
<form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
|
197 |
+
<?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
|
198 |
+
<input type="hidden" value="true" name="clear_log"/>
|
199 |
+
<p class="submit">
|
200 |
+
<input class="button" name="submit" value="<?php echo __( 'Clear Log', 'limit-login-attempts-reloaded' ); ?>"
|
201 |
+
type="submit"/>
|
202 |
+
</p>
|
203 |
+
</form>
|
204 |
+
|
205 |
+
<div class="limit-login-log">
|
206 |
+
<table class="form-table">
|
207 |
+
<tr>
|
208 |
+
<th scope="col"><?php _e( "Date", 'limit-login-attempts-reloaded' ); ?></th>
|
209 |
+
<th scope="col"><?php echo _x( "IP", "Internet address", 'limit-login-attempts-reloaded' ); ?></th>
|
210 |
+
<th scope="col"><?php _e( 'Tried to log in as', 'limit-login-attempts-reloaded' ); ?></th>
|
211 |
+
<th scope="col"><?php _e( 'Gateway', 'limit-login-attempts-reloaded' ); ?></th>
|
212 |
+
<th>
|
213 |
+
</tr>
|
214 |
+
|
215 |
+
<?php foreach ( $log as $date => $user_info ) : ?>
|
216 |
+
<tr>
|
217 |
+
<td class="limit-login-date"><?php echo date_i18n( 'F d, Y H:i', $date ); ?></td>
|
218 |
+
<td class="limit-login-ip">
|
219 |
+
<?php echo esc_html( $user_info['ip'] ); ?>
|
220 |
+
</td>
|
221 |
+
<td class="limit-login-max"><?php echo esc_html( $user_info['username'] ) . ' (' . esc_html( $user_info['counter'] ) .' lockouts)'; ?></td>
|
222 |
+
<td class="limit-login-gateway"><?php echo esc_html( $user_info['gateway'] ); ?></td>
|
223 |
+
<td>
|
224 |
+
<?php if ( !empty( $lockouts[ $user_info['ip'] ] ) && $lockouts[ $user_info['ip'] ] > time() ) : ?>
|
225 |
+
<a href="#" class="button limit-login-unlock" data-ip="<?=esc_attr($user_info['ip'])?>" data-username="<?=esc_attr($user_info['username'])?>">Unlock</a>
|
226 |
+
<?php elseif ( $user_info['unlocked'] ): ?>
|
227 |
+
Unlocked
|
228 |
+
<?php endif ?>
|
229 |
+
</tr>
|
230 |
+
<?php endforeach; ?>
|
231 |
+
|
232 |
+
</table>
|
233 |
+
</div>
|
234 |
+
<script>jQuery( function($) {
|
235 |
+
$('.limit-login-log .limit-login-unlock').click( function()
|
236 |
+
{
|
237 |
+
var btn = $(this);
|
238 |
+
|
239 |
+
if ( btn.hasClass('disabled') )
|
240 |
+
return false;
|
241 |
+
btn.addClass( 'disabled' );
|
242 |
+
|
243 |
+
$.post( ajaxurl, {
|
244 |
+
action: 'limit-login-unlock',
|
245 |
+
sec: '<?=wp_create_nonce('limit-login-unlock') ?>',
|
246 |
+
ip: btn.data('ip'),
|
247 |
+
username: btn.data('username')
|
248 |
+
} )
|
249 |
+
.done( function(data) {
|
250 |
+
if ( data === true )
|
251 |
+
btn.fadeOut( function(){ $(this).parent().text('Unlocked') });
|
252 |
+
else
|
253 |
+
fail();
|
254 |
+
}).fail( fail );
|
255 |
+
|
256 |
+
function fail() {
|
257 |
+
alert('Connection error');
|
258 |
+
btn.removeClass('disabled');
|
259 |
+
}
|
260 |
+
|
261 |
+
return false;
|
262 |
+
} );
|
263 |
+
} )</script>
|
264 |
+
<?php
|
265 |
+
} /* if showing $log */
|
266 |
+
?>
|
267 |
+
|