Limit Login Attempts Reloaded - Version 2.13.0

Version Description

  • Fixed incompatibility with PHP < 5.6.
  • Settings page layout refactored.
Download this release

Release Info

Developer wpchefgadget
Plugin Icon 128x128 Limit Login Attempts Reloaded
Version 2.13.0
Comparing to
See all releases

Code changes from version 2.12.3 to 2.13.0

assets/css/images/ui-icons_454545_256x240.png ADDED
Binary file
assets/css/jquery-ui.css ADDED
@@ -0,0 +1,1311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! jQuery UI - v1.12.1 - 2016-09-14
2
+ * http://jqueryui.com
3
+ * Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
4
+ * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
5
+ * Copyright jQuery Foundation and other contributors; Licensed MIT */
6
+
7
+ /* Layout helpers
8
+ ----------------------------------*/
9
+ .ui-helper-hidden {
10
+ display: none;
11
+ }
12
+ .ui-helper-hidden-accessible {
13
+ border: 0;
14
+ clip: rect(0 0 0 0);
15
+ height: 1px;
16
+ margin: -1px;
17
+ overflow: hidden;
18
+ padding: 0;
19
+ position: absolute;
20
+ width: 1px;
21
+ }
22
+ .ui-helper-reset {
23
+ margin: 0;
24
+ padding: 0;
25
+ border: 0;
26
+ outline: 0;
27
+ line-height: 1.3;
28
+ text-decoration: none;
29
+ font-size: 100%;
30
+ list-style: none;
31
+ }
32
+ .ui-helper-clearfix:before,
33
+ .ui-helper-clearfix:after {
34
+ content: "";
35
+ display: table;
36
+ border-collapse: collapse;
37
+ }
38
+ .ui-helper-clearfix:after {
39
+ clear: both;
40
+ }
41
+ .ui-helper-zfix {
42
+ width: 100%;
43
+ height: 100%;
44
+ top: 0;
45
+ left: 0;
46
+ position: absolute;
47
+ opacity: 0;
48
+ filter:Alpha(Opacity=0); /* support: IE8 */
49
+ }
50
+
51
+ .ui-front {
52
+ z-index: 100;
53
+ }
54
+
55
+
56
+ /* Interaction Cues
57
+ ----------------------------------*/
58
+ .ui-state-disabled {
59
+ cursor: default !important;
60
+ pointer-events: none;
61
+ }
62
+
63
+
64
+ /* Icons
65
+ ----------------------------------*/
66
+ .ui-icon {
67
+ display: inline-block;
68
+ vertical-align: middle;
69
+ margin-top: -.25em;
70
+ position: relative;
71
+ text-indent: -99999px;
72
+ overflow: hidden;
73
+ background-repeat: no-repeat;
74
+ }
75
+
76
+ .ui-widget-icon-block {
77
+ left: 50%;
78
+ margin-left: -8px;
79
+ display: block;
80
+ }
81
+
82
+ /* Misc visuals
83
+ ----------------------------------*/
84
+
85
+ /* Overlays */
86
+ .ui-widget-overlay {
87
+ position: fixed;
88
+ top: 0;
89
+ left: 0;
90
+ width: 100%;
91
+ height: 100%;
92
+ }
93
+ .ui-accordion .ui-accordion-header {
94
+ display: block;
95
+ cursor: pointer;
96
+ position: relative;
97
+ margin: 2px 0 0 0;
98
+ padding: .5em .5em .5em .7em;
99
+ font-size: 100%;
100
+ }
101
+ .ui-accordion .ui-accordion-content {
102
+ padding: 1em 2.2em;
103
+ border-top: 0;
104
+ overflow: auto;
105
+ }
106
+ .ui-autocomplete {
107
+ position: absolute;
108
+ top: 0;
109
+ left: 0;
110
+ cursor: default;
111
+ }
112
+ .ui-menu {
113
+ list-style: none;
114
+ padding: 0;
115
+ margin: 0;
116
+ display: block;
117
+ outline: 0;
118
+ }
119
+ .ui-menu .ui-menu {
120
+ position: absolute;
121
+ }
122
+ .ui-menu .ui-menu-item {
123
+ margin: 0;
124
+ cursor: pointer;
125
+ /* support: IE10, see #8844 */
126
+ list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
127
+ }
128
+ .ui-menu .ui-menu-item-wrapper {
129
+ position: relative;
130
+ padding: 3px 1em 3px .4em;
131
+ }
132
+ .ui-menu .ui-menu-divider {
133
+ margin: 5px 0;
134
+ height: 0;
135
+ font-size: 0;
136
+ line-height: 0;
137
+ border-width: 1px 0 0 0;
138
+ }
139
+ .ui-menu .ui-state-focus,
140
+ .ui-menu .ui-state-active {
141
+ margin: -1px;
142
+ }
143
+
144
+ /* icon support */
145
+ .ui-menu-icons {
146
+ position: relative;
147
+ }
148
+ .ui-menu-icons .ui-menu-item-wrapper {
149
+ padding-left: 2em;
150
+ }
151
+
152
+ /* left-aligned */
153
+ .ui-menu .ui-icon {
154
+ position: absolute;
155
+ top: 0;
156
+ bottom: 0;
157
+ left: .2em;
158
+ margin: auto 0;
159
+ }
160
+
161
+ /* right-aligned */
162
+ .ui-menu .ui-menu-icon {
163
+ left: auto;
164
+ right: 0;
165
+ }
166
+ .ui-button {
167
+ padding: .4em 1em;
168
+ display: inline-block;
169
+ position: relative;
170
+ line-height: normal;
171
+ margin-right: .1em;
172
+ cursor: pointer;
173
+ vertical-align: middle;
174
+ text-align: center;
175
+ -webkit-user-select: none;
176
+ -moz-user-select: none;
177
+ -ms-user-select: none;
178
+ user-select: none;
179
+
180
+ /* Support: IE <= 11 */
181
+ overflow: visible;
182
+ }
183
+
184
+ .ui-button,
185
+ .ui-button:link,
186
+ .ui-button:visited,
187
+ .ui-button:hover,
188
+ .ui-button:active {
189
+ text-decoration: none;
190
+ }
191
+
192
+ /* to make room for the icon, a width needs to be set here */
193
+ .ui-button-icon-only {
194
+ width: 2em;
195
+ box-sizing: border-box;
196
+ text-indent: -9999px;
197
+ white-space: nowrap;
198
+ }
199
+
200
+ /* no icon support for input elements */
201
+ input.ui-button.ui-button-icon-only {
202
+ text-indent: 0;
203
+ }
204
+
205
+ /* button icon element(s) */
206
+ .ui-button-icon-only .ui-icon {
207
+ position: absolute;
208
+ top: 50%;
209
+ left: 50%;
210
+ margin-top: -8px;
211
+ margin-left: -8px;
212
+ }
213
+
214
+ .ui-button.ui-icon-notext .ui-icon {
215
+ padding: 0;
216
+ width: 2.1em;
217
+ height: 2.1em;
218
+ text-indent: -9999px;
219
+ white-space: nowrap;
220
+
221
+ }
222
+
223
+ input.ui-button.ui-icon-notext .ui-icon {
224
+ width: auto;
225
+ height: auto;
226
+ text-indent: 0;
227
+ white-space: normal;
228
+ padding: .4em 1em;
229
+ }
230
+
231
+ /* workarounds */
232
+ /* Support: Firefox 5 - 40 */
233
+ input.ui-button::-moz-focus-inner,
234
+ button.ui-button::-moz-focus-inner {
235
+ border: 0;
236
+ padding: 0;
237
+ }
238
+ .ui-controlgroup {
239
+ vertical-align: middle;
240
+ display: inline-block;
241
+ }
242
+ .ui-controlgroup > .ui-controlgroup-item {
243
+ float: left;
244
+ margin-left: 0;
245
+ margin-right: 0;
246
+ }
247
+ .ui-controlgroup > .ui-controlgroup-item:focus,
248
+ .ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
249
+ z-index: 9999;
250
+ }
251
+ .ui-controlgroup-vertical > .ui-controlgroup-item {
252
+ display: block;
253
+ float: none;
254
+ width: 100%;
255
+ margin-top: 0;
256
+ margin-bottom: 0;
257
+ text-align: left;
258
+ }
259
+ .ui-controlgroup-vertical .ui-controlgroup-item {
260
+ box-sizing: border-box;
261
+ }
262
+ .ui-controlgroup .ui-controlgroup-label {
263
+ padding: .4em 1em;
264
+ }
265
+ .ui-controlgroup .ui-controlgroup-label span {
266
+ font-size: 80%;
267
+ }
268
+ .ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
269
+ border-left: none;
270
+ }
271
+ .ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
272
+ border-top: none;
273
+ }
274
+ .ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
275
+ border-right: none;
276
+ }
277
+ .ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
278
+ border-bottom: none;
279
+ }
280
+
281
+ /* Spinner specific style fixes */
282
+ .ui-controlgroup-vertical .ui-spinner-input {
283
+
284
+ /* Support: IE8 only, Android < 4.4 only */
285
+ width: 75%;
286
+ width: calc( 100% - 2.4em );
287
+ }
288
+ .ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
289
+ border-top-style: solid;
290
+ }
291
+
292
+ .ui-checkboxradio-label .ui-icon-background {
293
+ box-shadow: inset 1px 1px 1px #ccc;
294
+ border-radius: .12em;
295
+ border: none;
296
+ }
297
+ .ui-checkboxradio-radio-label .ui-icon-background {
298
+ width: 16px;
299
+ height: 16px;
300
+ border-radius: 1em;
301
+ overflow: visible;
302
+ border: none;
303
+ }
304
+ .ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
305
+ .ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
306
+ background-image: none;
307
+ width: 8px;
308
+ height: 8px;
309
+ border-width: 4px;
310
+ border-style: solid;
311
+ }
312
+ .ui-checkboxradio-disabled {
313
+ pointer-events: none;
314
+ }
315
+ .ui-datepicker {
316
+ width: 17em;
317
+ padding: .2em .2em 0;
318
+ display: none;
319
+ }
320
+ .ui-datepicker .ui-datepicker-header {
321
+ position: relative;
322
+ padding: .2em 0;
323
+ }
324
+ .ui-datepicker .ui-datepicker-prev,
325
+ .ui-datepicker .ui-datepicker-next {
326
+ position: absolute;
327
+ top: 2px;
328
+ width: 1.8em;
329
+ height: 1.8em;
330
+ }
331
+ .ui-datepicker .ui-datepicker-prev-hover,
332
+ .ui-datepicker .ui-datepicker-next-hover {
333
+ top: 1px;
334
+ }
335
+ .ui-datepicker .ui-datepicker-prev {
336
+ left: 2px;
337
+ }
338
+ .ui-datepicker .ui-datepicker-next {
339
+ right: 2px;
340
+ }
341
+ .ui-datepicker .ui-datepicker-prev-hover {
342
+ left: 1px;
343
+ }
344
+ .ui-datepicker .ui-datepicker-next-hover {
345
+ right: 1px;
346
+ }
347
+ .ui-datepicker .ui-datepicker-prev span,
348
+ .ui-datepicker .ui-datepicker-next span {
349
+ display: block;
350
+ position: absolute;
351
+ left: 50%;
352
+ margin-left: -8px;
353
+ top: 50%;
354
+ margin-top: -8px;
355
+ }
356
+ .ui-datepicker .ui-datepicker-title {
357
+ margin: 0 2.3em;
358
+ line-height: 1.8em;
359
+ text-align: center;
360
+ }
361
+ .ui-datepicker .ui-datepicker-title select {
362
+ font-size: 1em;
363
+ margin: 1px 0;
364
+ }
365
+ .ui-datepicker select.ui-datepicker-month,
366
+ .ui-datepicker select.ui-datepicker-year {
367
+ width: 45%;
368
+ }
369
+ .ui-datepicker table {
370
+ width: 100%;
371
+ font-size: .9em;
372
+ border-collapse: collapse;
373
+ margin: 0 0 .4em;
374
+ }
375
+ .ui-datepicker th {
376
+ padding: .7em .3em;
377
+ text-align: center;
378
+ font-weight: bold;
379
+ border: 0;
380
+ }
381
+ .ui-datepicker td {
382
+ border: 0;
383
+ padding: 1px;
384
+ }
385
+ .ui-datepicker td span,
386
+ .ui-datepicker td a {
387
+ display: block;
388
+ padding: .2em;
389
+ text-align: right;
390
+ text-decoration: none;
391
+ }
392
+ .ui-datepicker .ui-datepicker-buttonpane {
393
+ background-image: none;
394
+ margin: .7em 0 0 0;
395
+ padding: 0 .2em;
396
+ border-left: 0;
397
+ border-right: 0;
398
+ border-bottom: 0;
399
+ }
400
+ .ui-datepicker .ui-datepicker-buttonpane button {
401
+ float: right;
402
+ margin: .5em .2em .4em;
403
+ cursor: pointer;
404
+ padding: .2em .6em .3em .6em;
405
+ width: auto;
406
+ overflow: visible;
407
+ }
408
+ .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
409
+ float: left;
410
+ }
411
+
412
+ /* with multiple calendars */
413
+ .ui-datepicker.ui-datepicker-multi {
414
+ width: auto;
415
+ }
416
+ .ui-datepicker-multi .ui-datepicker-group {
417
+ float: left;
418
+ }
419
+ .ui-datepicker-multi .ui-datepicker-group table {
420
+ width: 95%;
421
+ margin: 0 auto .4em;
422
+ }
423
+ .ui-datepicker-multi-2 .ui-datepicker-group {
424
+ width: 50%;
425
+ }
426
+ .ui-datepicker-multi-3 .ui-datepicker-group {
427
+ width: 33.3%;
428
+ }
429
+ .ui-datepicker-multi-4 .ui-datepicker-group {
430
+ width: 25%;
431
+ }
432
+ .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
433
+ .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
434
+ border-left-width: 0;
435
+ }
436
+ .ui-datepicker-multi .ui-datepicker-buttonpane {
437
+ clear: left;
438
+ }
439
+ .ui-datepicker-row-break {
440
+ clear: both;
441
+ width: 100%;
442
+ font-size: 0;
443
+ }
444
+
445
+ /* RTL support */
446
+ .ui-datepicker-rtl {
447
+ direction: rtl;
448
+ }
449
+ .ui-datepicker-rtl .ui-datepicker-prev {
450
+ right: 2px;
451
+ left: auto;
452
+ }
453
+ .ui-datepicker-rtl .ui-datepicker-next {
454
+ left: 2px;
455
+ right: auto;
456
+ }
457
+ .ui-datepicker-rtl .ui-datepicker-prev:hover {
458
+ right: 1px;
459
+ left: auto;
460
+ }
461
+ .ui-datepicker-rtl .ui-datepicker-next:hover {
462
+ left: 1px;
463
+ right: auto;
464
+ }
465
+ .ui-datepicker-rtl .ui-datepicker-buttonpane {
466
+ clear: right;
467
+ }
468
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button {
469
+ float: left;
470
+ }
471
+ .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
472
+ .ui-datepicker-rtl .ui-datepicker-group {
473
+ float: right;
474
+ }
475
+ .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
476
+ .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
477
+ border-right-width: 0;
478
+ border-left-width: 1px;
479
+ }
480
+
481
+ /* Icons */
482
+ .ui-datepicker .ui-icon {
483
+ display: block;
484
+ text-indent: -99999px;
485
+ overflow: hidden;
486
+ background-repeat: no-repeat;
487
+ left: .5em;
488
+ top: .3em;
489
+ }
490
+ .ui-dialog {
491
+ position: absolute;
492
+ top: 0;
493
+ left: 0;
494
+ padding: .2em;
495
+ outline: 0;
496
+ }
497
+ .ui-dialog .ui-dialog-titlebar {
498
+ padding: .4em 1em;
499
+ position: relative;
500
+ }
501
+ .ui-dialog .ui-dialog-title {
502
+ float: left;
503
+ margin: .1em 0;
504
+ white-space: nowrap;
505
+ width: 90%;
506
+ overflow: hidden;
507
+ text-overflow: ellipsis;
508
+ }
509
+ .ui-dialog .ui-dialog-titlebar-close {
510
+ position: absolute;
511
+ right: .3em;
512
+ top: 50%;
513
+ width: 20px;
514
+ margin: -10px 0 0 0;
515
+ padding: 1px;
516
+ height: 20px;
517
+ }
518
+ .ui-dialog .ui-dialog-content {
519
+ position: relative;
520
+ border: 0;
521
+ padding: .5em 1em;
522
+ background: none;
523
+ overflow: auto;
524
+ }
525
+ .ui-dialog .ui-dialog-buttonpane {
526
+ text-align: left;
527
+ border-width: 1px 0 0 0;
528
+ background-image: none;
529
+ margin-top: .5em;
530
+ padding: .3em 1em .5em .4em;
531
+ }
532
+ .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
533
+ float: right;
534
+ }
535
+ .ui-dialog .ui-dialog-buttonpane button {
536
+ margin: .5em .4em .5em 0;
537
+ cursor: pointer;
538
+ }
539
+ .ui-dialog .ui-resizable-n {
540
+ height: 2px;
541
+ top: 0;
542
+ }
543
+ .ui-dialog .ui-resizable-e {
544
+ width: 2px;
545
+ right: 0;
546
+ }
547
+ .ui-dialog .ui-resizable-s {
548
+ height: 2px;
549
+ bottom: 0;
550
+ }
551
+ .ui-dialog .ui-resizable-w {
552
+ width: 2px;
553
+ left: 0;
554
+ }
555
+ .ui-dialog .ui-resizable-se,
556
+ .ui-dialog .ui-resizable-sw,
557
+ .ui-dialog .ui-resizable-ne,
558
+ .ui-dialog .ui-resizable-nw {
559
+ width: 7px;
560
+ height: 7px;
561
+ }
562
+ .ui-dialog .ui-resizable-se {
563
+ right: 0;
564
+ bottom: 0;
565
+ }
566
+ .ui-dialog .ui-resizable-sw {
567
+ left: 0;
568
+ bottom: 0;
569
+ }
570
+ .ui-dialog .ui-resizable-ne {
571
+ right: 0;
572
+ top: 0;
573
+ }
574
+ .ui-dialog .ui-resizable-nw {
575
+ left: 0;
576
+ top: 0;
577
+ }
578
+ .ui-draggable .ui-dialog-titlebar {
579
+ cursor: move;
580
+ }
581
+ .ui-draggable-handle {
582
+ -ms-touch-action: none;
583
+ touch-action: none;
584
+ }
585
+ .ui-resizable {
586
+ position: relative;
587
+ }
588
+ .ui-resizable-handle {
589
+ position: absolute;
590
+ font-size: 0.1px;
591
+ display: block;
592
+ -ms-touch-action: none;
593
+ touch-action: none;
594
+ }
595
+ .ui-resizable-disabled .ui-resizable-handle,
596
+ .ui-resizable-autohide .ui-resizable-handle {
597
+ display: none;
598
+ }
599
+ .ui-resizable-n {
600
+ cursor: n-resize;
601
+ height: 7px;
602
+ width: 100%;
603
+ top: -5px;
604
+ left: 0;
605
+ }
606
+ .ui-resizable-s {
607
+ cursor: s-resize;
608
+ height: 7px;
609
+ width: 100%;
610
+ bottom: -5px;
611
+ left: 0;
612
+ }
613
+ .ui-resizable-e {
614
+ cursor: e-resize;
615
+ width: 7px;
616
+ right: -5px;
617
+ top: 0;
618
+ height: 100%;
619
+ }
620
+ .ui-resizable-w {
621
+ cursor: w-resize;
622
+ width: 7px;
623
+ left: -5px;
624
+ top: 0;
625
+ height: 100%;
626
+ }
627
+ .ui-resizable-se {
628
+ cursor: se-resize;
629
+ width: 12px;
630
+ height: 12px;
631
+ right: 1px;
632
+ bottom: 1px;
633
+ }
634
+ .ui-resizable-sw {
635
+ cursor: sw-resize;
636
+ width: 9px;
637
+ height: 9px;
638
+ left: -5px;
639
+ bottom: -5px;
640
+ }
641
+ .ui-resizable-nw {
642
+ cursor: nw-resize;
643
+ width: 9px;
644
+ height: 9px;
645
+ left: -5px;
646
+ top: -5px;
647
+ }
648
+ .ui-resizable-ne {
649
+ cursor: ne-resize;
650
+ width: 9px;
651
+ height: 9px;
652
+ right: -5px;
653
+ top: -5px;
654
+ }
655
+ .ui-progressbar {
656
+ height: 2em;
657
+ text-align: left;
658
+ overflow: hidden;
659
+ }
660
+ .ui-progressbar .ui-progressbar-value {
661
+ margin: -1px;
662
+ height: 100%;
663
+ }
664
+ .ui-progressbar .ui-progressbar-overlay {
665
+ background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
666
+ height: 100%;
667
+ filter: alpha(opacity=25); /* support: IE8 */
668
+ opacity: 0.25;
669
+ }
670
+ .ui-progressbar-indeterminate .ui-progressbar-value {
671
+ background-image: none;
672
+ }
673
+ .ui-selectable {
674
+ -ms-touch-action: none;
675
+ touch-action: none;
676
+ }
677
+ .ui-selectable-helper {
678
+ position: absolute;
679
+ z-index: 100;
680
+ border: 1px dotted black;
681
+ }
682
+ .ui-selectmenu-menu {
683
+ padding: 0;
684
+ margin: 0;
685
+ position: absolute;
686
+ top: 0;
687
+ left: 0;
688
+ display: none;
689
+ }
690
+ .ui-selectmenu-menu .ui-menu {
691
+ overflow: auto;
692
+ overflow-x: hidden;
693
+ padding-bottom: 1px;
694
+ }
695
+ .ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
696
+ font-size: 1em;
697
+ font-weight: bold;
698
+ line-height: 1.5;
699
+ padding: 2px 0.4em;
700
+ margin: 0.5em 0 0 0;
701
+ height: auto;
702
+ border: 0;
703
+ }
704
+ .ui-selectmenu-open {
705
+ display: block;
706
+ }
707
+ .ui-selectmenu-text {
708
+ display: block;
709
+ margin-right: 20px;
710
+ overflow: hidden;
711
+ text-overflow: ellipsis;
712
+ }
713
+ .ui-selectmenu-button.ui-button {
714
+ text-align: left;
715
+ white-space: nowrap;
716
+ width: 14em;
717
+ }
718
+ .ui-selectmenu-icon.ui-icon {
719
+ float: right;
720
+ margin-top: 0;
721
+ }
722
+ .ui-slider {
723
+ position: relative;
724
+ text-align: left;
725
+ }
726
+ .ui-slider .ui-slider-handle {
727
+ position: absolute;
728
+ z-index: 2;
729
+ width: 1.2em;
730
+ height: 1.2em;
731
+ cursor: default;
732
+ -ms-touch-action: none;
733
+ touch-action: none;
734
+ }
735
+ .ui-slider .ui-slider-range {
736
+ position: absolute;
737
+ z-index: 1;
738
+ font-size: .7em;
739
+ display: block;
740
+ border: 0;
741
+ background-position: 0 0;
742
+ }
743
+
744
+ /* support: IE8 - See #6727 */
745
+ .ui-slider.ui-state-disabled .ui-slider-handle,
746
+ .ui-slider.ui-state-disabled .ui-slider-range {
747
+ filter: inherit;
748
+ }
749
+
750
+ .ui-slider-horizontal {
751
+ height: .8em;
752
+ }
753
+ .ui-slider-horizontal .ui-slider-handle {
754
+ top: -.3em;
755
+ margin-left: -.6em;
756
+ }
757
+ .ui-slider-horizontal .ui-slider-range {
758
+ top: 0;
759
+ height: 100%;
760
+ }
761
+ .ui-slider-horizontal .ui-slider-range-min {
762
+ left: 0;
763
+ }
764
+ .ui-slider-horizontal .ui-slider-range-max {
765
+ right: 0;
766
+ }
767
+
768
+ .ui-slider-vertical {
769
+ width: .8em;
770
+ height: 100px;
771
+ }
772
+ .ui-slider-vertical .ui-slider-handle {
773
+ left: -.3em;
774
+ margin-left: 0;
775
+ margin-bottom: -.6em;
776
+ }
777
+ .ui-slider-vertical .ui-slider-range {
778
+ left: 0;
779
+ width: 100%;
780
+ }
781
+ .ui-slider-vertical .ui-slider-range-min {
782
+ bottom: 0;
783
+ }
784
+ .ui-slider-vertical .ui-slider-range-max {
785
+ top: 0;
786
+ }
787
+ .ui-sortable-handle {
788
+ -ms-touch-action: none;
789
+ touch-action: none;
790
+ }
791
+ .ui-spinner {
792
+ position: relative;
793
+ display: inline-block;
794
+ overflow: hidden;
795
+ padding: 0;
796
+ vertical-align: middle;
797
+ }
798
+ .ui-spinner-input {
799
+ border: none;
800
+ background: none;
801
+ color: inherit;
802
+ padding: .222em 0;
803
+ margin: .2em 0;
804
+ vertical-align: middle;
805
+ margin-left: .4em;
806
+ margin-right: 2em;
807
+ }
808
+ .ui-spinner-button {
809
+ width: 1.6em;
810
+ height: 50%;
811
+ font-size: .5em;
812
+ padding: 0;
813
+ margin: 0;
814
+ text-align: center;
815
+ position: absolute;
816
+ cursor: default;
817
+ display: block;
818
+ overflow: hidden;
819
+ right: 0;
820
+ }
821
+ /* more specificity required here to override default borders */
822
+ .ui-spinner a.ui-spinner-button {
823
+ border-top-style: none;
824
+ border-bottom-style: none;
825
+ border-right-style: none;
826
+ }
827
+ .ui-spinner-up {
828
+ top: 0;
829
+ }
830
+ .ui-spinner-down {
831
+ bottom: 0;
832
+ }
833
+ .ui-tabs {
834
+ position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
835
+ padding: .2em;
836
+ }
837
+ .ui-tabs .ui-tabs-nav {
838
+ margin: 0;
839
+ padding: .2em .2em 0;
840
+ }
841
+ .ui-tabs .ui-tabs-nav li {
842
+ list-style: none;
843
+ float: left;
844
+ position: relative;
845
+ top: 0;
846
+ margin: 1px .2em 0 0;
847
+ border-bottom-width: 0;
848
+ padding: 0;
849
+ white-space: nowrap;
850
+ }
851
+ .ui-tabs .ui-tabs-nav .ui-tabs-anchor {
852
+ float: left;
853
+ padding: .5em 1em;
854
+ text-decoration: none;
855
+ }
856
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active {
857
+ margin-bottom: -1px;
858
+ padding-bottom: 1px;
859
+ }
860
+ .ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
861
+ .ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
862
+ .ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
863
+ cursor: text;
864
+ }
865
+ .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
866
+ cursor: pointer;
867
+ }
868
+ .ui-tabs .ui-tabs-panel {
869
+ display: block;
870
+ border-width: 0;
871
+ padding: 1em 1.4em;
872
+ background: none;
873
+ }
874
+ .ui-tooltip {
875
+ padding: 8px;
876
+ position: absolute;
877
+ z-index: 9999;
878
+ max-width: 300px;
879
+ }
880
+ body .ui-tooltip {
881
+ border-width: 2px;
882
+ }
883
+ /* Component containers
884
+ ----------------------------------*/
885
+ .ui-widget {
886
+ font-family: Verdana,Arial,sans-serif;
887
+ font-size: 1.1em;
888
+ }
889
+ .ui-widget .ui-widget {
890
+ font-size: 1em;
891
+ }
892
+ .ui-widget input,
893
+ .ui-widget select,
894
+ .ui-widget textarea,
895
+ .ui-widget button {
896
+ font-family: Verdana,Arial,sans-serif;
897
+ font-size: 1em;
898
+ }
899
+ .ui-widget.ui-widget-content {
900
+ border: 1px solid #d3d3d3;
901
+ }
902
+ .ui-widget-content {
903
+ border: 1px solid #aaaaaa;
904
+ background: #ffffff;
905
+ color: #222222;
906
+ }
907
+ .ui-widget-content a {
908
+ color: #222222;
909
+ }
910
+ .ui-widget-header {
911
+ border: 1px solid #aaaaaa;
912
+ background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
913
+ color: #222222;
914
+ font-weight: bold;
915
+ }
916
+ .ui-widget-header a {
917
+ color: #222222;
918
+ }
919
+
920
+ /* Interaction states
921
+ ----------------------------------*/
922
+ .ui-state-default,
923
+ .ui-widget-content .ui-state-default,
924
+ .ui-widget-header .ui-state-default,
925
+ .ui-button,
926
+
927
+ /* We use html here because we need a greater specificity to make sure disabled
928
+ works properly when clicked or hovered */
929
+ html .ui-button.ui-state-disabled:hover,
930
+ html .ui-button.ui-state-disabled:active {
931
+ border: 1px solid #d3d3d3;
932
+ background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
933
+ font-weight: normal;
934
+ color: #555555;
935
+ }
936
+ .ui-state-default a,
937
+ .ui-state-default a:link,
938
+ .ui-state-default a:visited,
939
+ a.ui-button,
940
+ a:link.ui-button,
941
+ a:visited.ui-button,
942
+ .ui-button {
943
+ color: #555555;
944
+ text-decoration: none;
945
+ }
946
+ .ui-state-hover,
947
+ .ui-widget-content .ui-state-hover,
948
+ .ui-widget-header .ui-state-hover,
949
+ .ui-state-focus,
950
+ .ui-widget-content .ui-state-focus,
951
+ .ui-widget-header .ui-state-focus,
952
+ .ui-button:hover,
953
+ .ui-button:focus {
954
+ border: 1px solid #999999;
955
+ background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
956
+ font-weight: normal;
957
+ color: #212121;
958
+ }
959
+ .ui-state-hover a,
960
+ .ui-state-hover a:hover,
961
+ .ui-state-hover a:link,
962
+ .ui-state-hover a:visited,
963
+ .ui-state-focus a,
964
+ .ui-state-focus a:hover,
965
+ .ui-state-focus a:link,
966
+ .ui-state-focus a:visited,
967
+ a.ui-button:hover,
968
+ a.ui-button:focus {
969
+ color: #212121;
970
+ text-decoration: none;
971
+ }
972
+
973
+ .ui-visual-focus {
974
+ box-shadow: 0 0 3px 1px rgb(94, 158, 214);
975
+ }
976
+ .ui-state-active,
977
+ .ui-widget-content .ui-state-active,
978
+ .ui-widget-header .ui-state-active,
979
+ a.ui-button:active,
980
+ .ui-button:active,
981
+ .ui-button.ui-state-active:hover {
982
+ border: 1px solid #aaaaaa;
983
+ background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
984
+ font-weight: normal;
985
+ color: #212121;
986
+ }
987
+ .ui-icon-background,
988
+ .ui-state-active .ui-icon-background {
989
+ border: #aaaaaa;
990
+ background-color: #212121;
991
+ }
992
+ .ui-state-active a,
993
+ .ui-state-active a:link,
994
+ .ui-state-active a:visited {
995
+ color: #212121;
996
+ text-decoration: none;
997
+ }
998
+
999
+ /* Interaction Cues
1000
+ ----------------------------------*/
1001
+ .ui-state-highlight,
1002
+ .ui-widget-content .ui-state-highlight,
1003
+ .ui-widget-header .ui-state-highlight {
1004
+ border: 1px solid #fcefa1;
1005
+ background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
1006
+ color: #363636;
1007
+ }
1008
+ .ui-state-checked {
1009
+ border: 1px solid #fcefa1;
1010
+ background: #fbf9ee;
1011
+ }
1012
+ .ui-state-highlight a,
1013
+ .ui-widget-content .ui-state-highlight a,
1014
+ .ui-widget-header .ui-state-highlight a {
1015
+ color: #363636;
1016
+ }
1017
+ .ui-state-error,
1018
+ .ui-widget-content .ui-state-error,
1019
+ .ui-widget-header .ui-state-error {
1020
+ border: 1px solid #cd0a0a;
1021
+ background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
1022
+ color: #cd0a0a;
1023
+ }
1024
+ .ui-state-error a,
1025
+ .ui-widget-content .ui-state-error a,
1026
+ .ui-widget-header .ui-state-error a {
1027
+ color: #cd0a0a;
1028
+ }
1029
+ .ui-state-error-text,
1030
+ .ui-widget-content .ui-state-error-text,
1031
+ .ui-widget-header .ui-state-error-text {
1032
+ color: #cd0a0a;
1033
+ }
1034
+ .ui-priority-primary,
1035
+ .ui-widget-content .ui-priority-primary,
1036
+ .ui-widget-header .ui-priority-primary {
1037
+ font-weight: bold;
1038
+ }
1039
+ .ui-priority-secondary,
1040
+ .ui-widget-content .ui-priority-secondary,
1041
+ .ui-widget-header .ui-priority-secondary {
1042
+ opacity: .7;
1043
+ filter:Alpha(Opacity=70); /* support: IE8 */
1044
+ font-weight: normal;
1045
+ }
1046
+ .ui-state-disabled,
1047
+ .ui-widget-content .ui-state-disabled,
1048
+ .ui-widget-header .ui-state-disabled {
1049
+ opacity: .35;
1050
+ filter:Alpha(Opacity=35); /* support: IE8 */
1051
+ background-image: none;
1052
+ }
1053
+ .ui-state-disabled .ui-icon {
1054
+ filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
1055
+ }
1056
+
1057
+ /* Icons
1058
+ ----------------------------------*/
1059
+
1060
+ /* states and images */
1061
+ .ui-icon {
1062
+ width: 16px;
1063
+ height: 16px;
1064
+ }
1065
+ .ui-icon,
1066
+ .ui-widget-content .ui-icon {
1067
+ background-image: url("images/ui-icons_222222_256x240.png");
1068
+ }
1069
+ .ui-widget-header .ui-icon {
1070
+ background-image: url("images/ui-icons_222222_256x240.png");
1071
+ }
1072
+ .ui-state-hover .ui-icon,
1073
+ .ui-state-focus .ui-icon,
1074
+ .ui-button:hover .ui-icon,
1075
+ .ui-button:focus .ui-icon {
1076
+ background-image: url("images/ui-icons_454545_256x240.png");
1077
+ }
1078
+ .ui-state-active .ui-icon,
1079
+ .ui-button:active .ui-icon {
1080
+ background-image: url("images/ui-icons_454545_256x240.png");
1081
+ }
1082
+ .ui-state-highlight .ui-icon,
1083
+ .ui-button .ui-state-highlight.ui-icon {
1084
+ background-image: url("images/ui-icons_2e83ff_256x240.png");
1085
+ }
1086
+ .ui-state-error .ui-icon,
1087
+ .ui-state-error-text .ui-icon {
1088
+ background-image: url("images/ui-icons_cd0a0a_256x240.png");
1089
+ }
1090
+ .ui-button .ui-icon {
1091
+ background-image: url("images/ui-icons_888888_256x240.png");
1092
+ }
1093
+
1094
+ /* positioning */
1095
+ .ui-icon-blank { background-position: 16px 16px; }
1096
+ .ui-icon-caret-1-n { background-position: 0 0; }
1097
+ .ui-icon-caret-1-ne { background-position: -16px 0; }
1098
+ .ui-icon-caret-1-e { background-position: -32px 0; }
1099
+ .ui-icon-caret-1-se { background-position: -48px 0; }
1100
+ .ui-icon-caret-1-s { background-position: -65px 0; }
1101
+ .ui-icon-caret-1-sw { background-position: -80px 0; }
1102
+ .ui-icon-caret-1-w { background-position: -96px 0; }
1103
+ .ui-icon-caret-1-nw { background-position: -112px 0; }
1104
+ .ui-icon-caret-2-n-s { background-position: -128px 0; }
1105
+ .ui-icon-caret-2-e-w { background-position: -144px 0; }
1106
+ .ui-icon-triangle-1-n { background-position: 0 -16px; }
1107
+ .ui-icon-triangle-1-ne { background-position: -16px -16px; }
1108
+ .ui-icon-triangle-1-e { background-position: -32px -16px; }
1109
+ .ui-icon-triangle-1-se { background-position: -48px -16px; }
1110
+ .ui-icon-triangle-1-s { background-position: -65px -16px; }
1111
+ .ui-icon-triangle-1-sw { background-position: -80px -16px; }
1112
+ .ui-icon-triangle-1-w { background-position: -96px -16px; }
1113
+ .ui-icon-triangle-1-nw { background-position: -112px -16px; }
1114
+ .ui-icon-triangle-2-n-s { background-position: -128px -16px; }
1115
+ .ui-icon-triangle-2-e-w { background-position: -144px -16px; }
1116
+ .ui-icon-arrow-1-n { background-position: 0 -32px; }
1117
+ .ui-icon-arrow-1-ne { background-position: -16px -32px; }
1118
+ .ui-icon-arrow-1-e { background-position: -32px -32px; }
1119
+ .ui-icon-arrow-1-se { background-position: -48px -32px; }
1120
+ .ui-icon-arrow-1-s { background-position: -65px -32px; }
1121
+ .ui-icon-arrow-1-sw { background-position: -80px -32px; }
1122
+ .ui-icon-arrow-1-w { background-position: -96px -32px; }
1123
+ .ui-icon-arrow-1-nw { background-position: -112px -32px; }
1124
+ .ui-icon-arrow-2-n-s { background-position: -128px -32px; }
1125
+ .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
1126
+ .ui-icon-arrow-2-e-w { background-position: -160px -32px; }
1127
+ .ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
1128
+ .ui-icon-arrowstop-1-n { background-position: -192px -32px; }
1129
+ .ui-icon-arrowstop-1-e { background-position: -208px -32px; }
1130
+ .ui-icon-arrowstop-1-s { background-position: -224px -32px; }
1131
+ .ui-icon-arrowstop-1-w { background-position: -240px -32px; }
1132
+ .ui-icon-arrowthick-1-n { background-position: 1px -48px; }
1133
+ .ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
1134
+ .ui-icon-arrowthick-1-e { background-position: -32px -48px; }
1135
+ .ui-icon-arrowthick-1-se { background-position: -48px -48px; }
1136
+ .ui-icon-arrowthick-1-s { background-position: -64px -48px; }
1137
+ .ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
1138
+ .ui-icon-arrowthick-1-w { background-position: -96px -48px; }
1139
+ .ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
1140
+ .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
1141
+ .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
1142
+ .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
1143
+ .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
1144
+ .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
1145
+ .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
1146
+ .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
1147
+ .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
1148
+ .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
1149
+ .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
1150
+ .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
1151
+ .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
1152
+ .ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
1153
+ .ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
1154
+ .ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
1155
+ .ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
1156
+ .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
1157
+ .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
1158
+ .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
1159
+ .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
1160
+ .ui-icon-arrow-4 { background-position: 0 -80px; }
1161
+ .ui-icon-arrow-4-diag { background-position: -16px -80px; }
1162
+ .ui-icon-extlink { background-position: -32px -80px; }
1163
+ .ui-icon-newwin { background-position: -48px -80px; }
1164
+ .ui-icon-refresh { background-position: -64px -80px; }
1165
+ .ui-icon-shuffle { background-position: -80px -80px; }
1166
+ .ui-icon-transfer-e-w { background-position: -96px -80px; }
1167
+ .ui-icon-transferthick-e-w { background-position: -112px -80px; }
1168
+ .ui-icon-folder-collapsed { background-position: 0 -96px; }
1169
+ .ui-icon-folder-open { background-position: -16px -96px; }
1170
+ .ui-icon-document { background-position: -32px -96px; }
1171
+ .ui-icon-document-b { background-position: -48px -96px; }
1172
+ .ui-icon-note { background-position: -64px -96px; }
1173
+ .ui-icon-mail-closed { background-position: -80px -96px; }
1174
+ .ui-icon-mail-open { background-position: -96px -96px; }
1175
+ .ui-icon-suitcase { background-position: -112px -96px; }
1176
+ .ui-icon-comment { background-position: -128px -96px; }
1177
+ .ui-icon-person { background-position: -144px -96px; }
1178
+ .ui-icon-print { background-position: -160px -96px; }
1179
+ .ui-icon-trash { background-position: -176px -96px; }
1180
+ .ui-icon-locked { background-position: -192px -96px; }
1181
+ .ui-icon-unlocked { background-position: -208px -96px; }
1182
+ .ui-icon-bookmark { background-position: -224px -96px; }
1183
+ .ui-icon-tag { background-position: -240px -96px; }
1184
+ .ui-icon-home { background-position: 0 -112px; }
1185
+ .ui-icon-flag { background-position: -16px -112px; }
1186
+ .ui-icon-calendar { background-position: -32px -112px; }
1187
+ .ui-icon-cart { background-position: -48px -112px; }
1188
+ .ui-icon-pencil { background-position: -64px -112px; }
1189
+ .ui-icon-clock { background-position: -80px -112px; }
1190
+ .ui-icon-disk { background-position: -96px -112px; }
1191
+ .ui-icon-calculator { background-position: -112px -112px; }
1192
+ .ui-icon-zoomin { background-position: -128px -112px; }
1193
+ .ui-icon-zoomout { background-position: -144px -112px; }
1194
+ .ui-icon-search { background-position: -160px -112px; }
1195
+ .ui-icon-wrench { background-position: -176px -112px; }
1196
+ .ui-icon-gear { background-position: -192px -112px; }
1197
+ .ui-icon-heart { background-position: -208px -112px; }
1198
+ .ui-icon-star { background-position: -224px -112px; }
1199
+ .ui-icon-link { background-position: -240px -112px; }
1200
+ .ui-icon-cancel { background-position: 0 -128px; }
1201
+ .ui-icon-plus { background-position: -16px -128px; }
1202
+ .ui-icon-plusthick { background-position: -32px -128px; }
1203
+ .ui-icon-minus { background-position: -48px -128px; }
1204
+ .ui-icon-minusthick { background-position: -64px -128px; }
1205
+ .ui-icon-close { background-position: -80px -128px; }
1206
+ .ui-icon-closethick { background-position: -96px -128px; }
1207
+ .ui-icon-key { background-position: -112px -128px; }
1208
+ .ui-icon-lightbulb { background-position: -128px -128px; }
1209
+ .ui-icon-scissors { background-position: -144px -128px; }
1210
+ .ui-icon-clipboard { background-position: -160px -128px; }
1211
+ .ui-icon-copy { background-position: -176px -128px; }
1212
+ .ui-icon-contact { background-position: -192px -128px; }
1213
+ .ui-icon-image { background-position: -208px -128px; }
1214
+ .ui-icon-video { background-position: -224px -128px; }
1215
+ .ui-icon-script { background-position: -240px -128px; }
1216
+ .ui-icon-alert { background-position: 0 -144px; }
1217
+ .ui-icon-info { background-position: -16px -144px; }
1218
+ .ui-icon-notice { background-position: -32px -144px; }
1219
+ .ui-icon-help { background-position: -48px -144px; }
1220
+ .ui-icon-check { background-position: -64px -144px; }
1221
+ .ui-icon-bullet { background-position: -80px -144px; }
1222
+ .ui-icon-radio-on { background-position: -96px -144px; }
1223
+ .ui-icon-radio-off { background-position: -112px -144px; }
1224
+ .ui-icon-pin-w { background-position: -128px -144px; }
1225
+ .ui-icon-pin-s { background-position: -144px -144px; }
1226
+ .ui-icon-play { background-position: 0 -160px; }
1227
+ .ui-icon-pause { background-position: -16px -160px; }
1228
+ .ui-icon-seek-next { background-position: -32px -160px; }
1229
+ .ui-icon-seek-prev { background-position: -48px -160px; }
1230
+ .ui-icon-seek-end { background-position: -64px -160px; }
1231
+ .ui-icon-seek-start { background-position: -80px -160px; }
1232
+ /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
1233
+ .ui-icon-seek-first { background-position: -80px -160px; }
1234
+ .ui-icon-stop { background-position: -96px -160px; }
1235
+ .ui-icon-eject { background-position: -112px -160px; }
1236
+ .ui-icon-volume-off { background-position: -128px -160px; }
1237
+ .ui-icon-volume-on { background-position: -144px -160px; }
1238
+ .ui-icon-power { background-position: 0 -176px; }
1239
+ .ui-icon-signal-diag { background-position: -16px -176px; }
1240
+ .ui-icon-signal { background-position: -32px -176px; }
1241
+ .ui-icon-battery-0 { background-position: -48px -176px; }
1242
+ .ui-icon-battery-1 { background-position: -64px -176px; }
1243
+ .ui-icon-battery-2 { background-position: -80px -176px; }
1244
+ .ui-icon-battery-3 { background-position: -96px -176px; }
1245
+ .ui-icon-circle-plus { background-position: 0 -192px; }
1246
+ .ui-icon-circle-minus { background-position: -16px -192px; }
1247
+ .ui-icon-circle-close { background-position: -32px -192px; }
1248
+ .ui-icon-circle-triangle-e { background-position: -48px -192px; }
1249
+ .ui-icon-circle-triangle-s { background-position: -64px -192px; }
1250
+ .ui-icon-circle-triangle-w { background-position: -80px -192px; }
1251
+ .ui-icon-circle-triangle-n { background-position: -96px -192px; }
1252
+ .ui-icon-circle-arrow-e { background-position: -112px -192px; }
1253
+ .ui-icon-circle-arrow-s { background-position: -128px -192px; }
1254
+ .ui-icon-circle-arrow-w { background-position: -144px -192px; }
1255
+ .ui-icon-circle-arrow-n { background-position: -160px -192px; }
1256
+ .ui-icon-circle-zoomin { background-position: -176px -192px; }
1257
+ .ui-icon-circle-zoomout { background-position: -192px -192px; }
1258
+ .ui-icon-circle-check { background-position: -208px -192px; }
1259
+ .ui-icon-circlesmall-plus { background-position: 0 -208px; }
1260
+ .ui-icon-circlesmall-minus { background-position: -16px -208px; }
1261
+ .ui-icon-circlesmall-close { background-position: -32px -208px; }
1262
+ .ui-icon-squaresmall-plus { background-position: -48px -208px; }
1263
+ .ui-icon-squaresmall-minus { background-position: -64px -208px; }
1264
+ .ui-icon-squaresmall-close { background-position: -80px -208px; }
1265
+ .ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
1266
+ .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
1267
+ .ui-icon-grip-solid-vertical { background-position: -32px -224px; }
1268
+ .ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
1269
+ .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
1270
+ .ui-icon-grip-diagonal-se { background-position: -80px -224px; }
1271
+
1272
+
1273
+ /* Misc visuals
1274
+ ----------------------------------*/
1275
+
1276
+ /* Corner radius */
1277
+ .ui-corner-all,
1278
+ .ui-corner-top,
1279
+ .ui-corner-left,
1280
+ .ui-corner-tl {
1281
+ border-top-left-radius: 4px;
1282
+ }
1283
+ .ui-corner-all,
1284
+ .ui-corner-top,
1285
+ .ui-corner-right,
1286
+ .ui-corner-tr {
1287
+ border-top-right-radius: 4px;
1288
+ }
1289
+ .ui-corner-all,
1290
+ .ui-corner-bottom,
1291
+ .ui-corner-left,
1292
+ .ui-corner-bl {
1293
+ border-bottom-left-radius: 4px;
1294
+ }
1295
+ .ui-corner-all,
1296
+ .ui-corner-bottom,
1297
+ .ui-corner-right,
1298
+ .ui-corner-br {
1299
+ border-bottom-right-radius: 4px;
1300
+ }
1301
+
1302
+ /* Overlays */
1303
+ .ui-widget-overlay {
1304
+ background: #aaaaaa;
1305
+ opacity: .3;
1306
+ filter: Alpha(Opacity=30); /* support: IE8 */
1307
+ }
1308
+ .ui-widget-shadow {
1309
+ -webkit-box-shadow: -8px -8px 8px #aaaaaa;
1310
+ box-shadow: -8px -8px 8px #aaaaaa;
1311
+ }
assets/css/limit-login-attempts.css CHANGED
@@ -1 +1 @@
1
- .limit-login-page-settings .field-col{display:inline-block;margin-right:20px}.limit-login-page-settings .limit-login-log table{background-color:#fff}.limit-login-page-settings .limit-login-log table th,.limit-login-page-settings .limit-login-log table td{padding:10px}.limit-login-page-settings .limit-login-log table tr:nth-child(even){background-color:rgba(0,0,0,0.09)}.limit-login-page-settings input[name="admin_notify_email"]{min-width:243px}.llar-notice-review{display:-webkit-box;display:-ms-flexbox;display:flex;padding:15px 20px 0 !important;border-left:4px solid #333 !important}.llar-notice-review .llar-review-image img{margin-top:10px}.llar-notice-review .llar-review-info{-webkit-box-flex:1;-ms-flex:1;flex:1;margin-left:30px}.llar-notice-review .llar-review-info .llar-buttons{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.llar-notice-review .llar-review-info .llar-buttons li{margin-right:10px}.llar-notice-review .llar-review-info .llar-buttons li .dashicons{margin-right:5px}
1
+ .limit-login-page-settings .field-col{display:inline-block;margin-right:20px}.limit-login-page-settings .limit-login-log table{background-color:#fff}.limit-login-page-settings .limit-login-log table th,.limit-login-page-settings .limit-login-log table td{padding:10px}.limit-login-page-settings .limit-login-log table tr:nth-child(even){background-color:rgba(0,0,0,0.09)}.limit-login-page-settings input[name="admin_notify_email"]{min-width:243px}.llar-notice-review{display:-webkit-box;display:-ms-flexbox;display:flex;padding:15px 20px 0 !important;border-left:4px solid #333 !important}.llar-notice-review .llar-review-image img{margin-top:10px}.llar-notice-review .llar-review-info{-webkit-box-flex:1;-ms-flex:1;flex:1;margin-left:30px}.llar-notice-review .llar-review-info .llar-buttons{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.llar-notice-review .llar-review-info .llar-buttons li{margin-right:10px}.llar-notice-review .llar-review-info .llar-buttons li .dashicons{margin-right:5px}.llar-accordion .ui-accordion-header{font-weight:bold;background-color:#778899;color:#fff}.llar-accordion .ui-accordion-header.ui-accordion-header-active{background-color:#87CEFA}
assets/sass/limit-login-attempts.scss CHANGED
@@ -47,4 +47,16 @@
47
  }
48
  }
49
  }
 
 
 
 
 
 
 
 
 
 
 
 
50
  }
47
  }
48
  }
49
  }
50
+ }
51
+
52
+ .llar-accordion {
53
+ .ui-accordion-header {
54
+ font-weight: bold;
55
+ background-color: #778899;
56
+ color: #fff;
57
+
58
+ &.ui-accordion-header-active {
59
+ background-color: #87CEFA;
60
+ }
61
+ }
62
  }
core/LimitLoginAttempts.php CHANGED
@@ -79,6 +79,8 @@ class Limit_Login_Attempts
79
  add_filter( 'illegal_user_logins', array( $this, 'register_user_blacklist' ), 999 );
80
  add_action( 'admin_notices', array( $this, 'show_leave_review_notice' ) );
81
  add_action( 'wp_ajax_dismiss_review_notice', array( $this, 'dismiss_review_notice_callback' ));
 
 
82
  }
83
 
84
  /**
@@ -146,6 +148,12 @@ class Limit_Login_Attempts
146
  add_action('wp_ajax_limit-login-unlock', array( $this, 'ajax_unlock' ) );
147
  }
148
 
 
 
 
 
 
 
149
  /**
150
  * @param $user Wp_User
151
  */
@@ -500,10 +508,17 @@ class Limit_Login_Attempts
500
  */
501
  public function get_options_page_uri()
502
  {
 
503
  if ( is_network_admin() )
504
- return network_admin_url( 'settings.php?page=limit-login-attempts' );
 
 
505
 
506
- return menu_page_url( $this->_options_page_slug, false );
 
 
 
 
507
  }
508
 
509
  /**
@@ -720,6 +735,11 @@ class Limit_Login_Attempts
720
  public function notify( $user ) {
721
  $args = explode( ',', $this->get_option( 'lockout_notify' ) );
722
 
 
 
 
 
 
723
  if ( empty( $args ) ) {
724
  return;
725
  }
@@ -1302,15 +1322,6 @@ class Limit_Login_Attempts
1302
  elseif ( $this->network_mode )
1303
  $this->update_option( 'use_local_options', empty($_POST['use_global_options']) );
1304
 
1305
- /* Should we support GDPR */
1306
- if( isset( $_POST[ 'gdpr' ] ) )
1307
- {
1308
- $this->update_option( 'gdpr', 1 );
1309
- }
1310
- else {
1311
- $this->update_option( 'gdpr', 0 );
1312
- }
1313
-
1314
  /* Should we clear log? */
1315
  if( isset( $_POST[ 'clear_log' ] ) )
1316
  {
@@ -1333,16 +1344,7 @@ class Limit_Login_Attempts
1333
  }
1334
 
1335
  /* Should we update options? */
1336
- if( isset( $_POST[ 'update_options' ] ) )
1337
- {
1338
- $this->update_option('allowed_retries', (int)$_POST['allowed_retries'] );
1339
- $this->update_option('lockout_duration', (int)$_POST['lockout_duration'] * 60 );
1340
- $this->update_option('valid_duration', (int)$_POST['valid_duration'] * 3600 );
1341
- $this->update_option('allowed_lockouts', (int)$_POST['allowed_lockouts'] );
1342
- $this->update_option('long_duration', (int)$_POST['long_duration'] * 3600 );
1343
- $this->update_option('notify_email_after', (int)$_POST['email_after'] );
1344
-
1345
- $this->update_option('admin_notify_email', sanitize_email( $_POST['admin_notify_email'] ) );
1346
 
1347
  $white_list_ips = ( !empty( $_POST['lla_whitelist_ips'] ) ) ? explode("\n", str_replace("\r", "", stripslashes($_POST['lla_whitelist_ips']) ) ) : array();
1348
 
@@ -1392,10 +1394,33 @@ class Limit_Login_Attempts
1392
  }
1393
  $this->update_option('blacklist_usernames', $black_list_usernames );
1394
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1395
 
1396
  $trusted_ip_origins = ( !empty( $_POST['lla_trusted_ip_origins'] ) )
1397
- ? array_map( 'trim', explode( ',', sanitize_text_field( $_POST['lla_trusted_ip_origins'] ) ) )
1398
- : array();
1399
 
1400
  if( !in_array( 'REMOTE_ADDR', $trusted_ip_origins ) ) {
1401
 
@@ -1404,7 +1429,6 @@ class Limit_Login_Attempts
1404
 
1405
  $this->update_option('trusted_ip_origins', $trusted_ip_origins );
1406
 
1407
-
1408
  $notify_methods = array();
1409
  if( isset( $_POST[ 'lockout_notify_log' ] ) ) {
1410
  $notify_methods[] = 'log';
@@ -1416,8 +1440,8 @@ class Limit_Login_Attempts
1416
 
1417
  $this->sanitize_options();
1418
 
1419
- $this->show_error( __( 'Options saved.', 'limit-login-attempts-reloaded' ) );
1420
- }
1421
  }
1422
 
1423
  include_once( LLA_PLUGIN_DIR . '/views/options-page.php' );
@@ -1535,8 +1559,8 @@ class Limit_Login_Attempts
1535
  </div>
1536
  <div class="llar-review-info">
1537
  <p><?php _e('Hey <strong>Limit Login Attempts Reloaded</strong> user!', 'limit-login-attempts-reloaded'); ?></p>
1538
- <p><?php _e('A <strong>crazy idea</strong> we wanted to share! What if we put an image from YOU on the <a href="https://wordpress.org/plugins/limit-login-attempts-reloaded/" target="_blank">LLAR page</a>?! (<a href="https://wordpress.org/plugins/hello-dolly/" target="_blank">example</a>) A drawing made by you or your child would cheer people up! Send us your drawing by <a href="mailto:wpchef.me@gmail.com" target="_blank">email</a> and we like it, we\'ll add it in the next release. Let\'s have some fun!', 'limit-login-attempts-reloaded'); ?></p>
1539
- <p><?php _e('Also, we would really like to hear your feedback about the plugin! Please take a couple minutes to write a few words <a href="https://wordpress.org/support/plugin/limit-login-attempts-reloaded/reviews/#new-post" target="_blank">here</a>. Thank you!', 'limit-login-attempts-reloaded'); ?></p>
1540
 
1541
  <ul class="llar-buttons">
1542
  <li><a href="#" class="llar-review-dismiss" data-type="dismiss"><?php _e('Don\'t show again', 'limit-login-attempts-reloaded'); ?></a></li>
@@ -1592,7 +1616,7 @@ class Limit_Login_Attempts
1592
 
1593
  if ( !current_user_can('activate_plugins') ) {
1594
 
1595
- wp_send_json_error([]);
1596
  }
1597
 
1598
  check_ajax_referer('llar-action', 'sec');
@@ -1609,6 +1633,6 @@ class Limit_Login_Attempts
1609
  $this->update_option( 'activation_timestamp', strtotime("+1 month") );
1610
  }
1611
 
1612
- wp_send_json_success([]);
1613
  }
1614
  }
79
  add_filter( 'illegal_user_logins', array( $this, 'register_user_blacklist' ), 999 );
80
  add_action( 'admin_notices', array( $this, 'show_leave_review_notice' ) );
81
  add_action( 'wp_ajax_dismiss_review_notice', array( $this, 'dismiss_review_notice_callback' ));
82
+
83
+ add_action( 'admin_print_scripts-settings_page_limit-login-attempts', array( $this, 'load_admin_scripts' ) );
84
  }
85
 
86
  /**
148
  add_action('wp_ajax_limit-login-unlock', array( $this, 'ajax_unlock' ) );
149
  }
150
 
151
+ public function load_admin_scripts() {
152
+
153
+ wp_enqueue_script('jquery-ui-accordion');
154
+ wp_enqueue_style('llar-jquery-ui', LLA_PLUGIN_URL.'assets/css/jquery-ui.css');
155
+ }
156
+
157
  /**
158
  * @param $user Wp_User
159
  */
508
  */
509
  public function get_options_page_uri()
510
  {
511
+
512
  if ( is_network_admin() )
513
+ $uri = network_admin_url( 'settings.php?page=limit-login-attempts' );
514
+ else
515
+ $uri = menu_page_url( $this->_options_page_slug, false );
516
 
517
+ if(!empty($_GET['tab'])) {
518
+ $uri .= '&tab='.$_GET['tab'];
519
+ }
520
+
521
+ return $uri;
522
  }
523
 
524
  /**
735
  public function notify( $user ) {
736
  $args = explode( ',', $this->get_option( 'lockout_notify' ) );
737
 
738
+ // TODO: Maybe temporarily
739
+ if(!in_array('log', $args)) {
740
+ $args[] = 'log';
741
+ }
742
+
743
  if ( empty( $args ) ) {
744
  return;
745
  }
1322
  elseif ( $this->network_mode )
1323
  $this->update_option( 'use_local_options', empty($_POST['use_global_options']) );
1324
 
 
 
 
 
 
 
 
 
 
1325
  /* Should we clear log? */
1326
  if( isset( $_POST[ 'clear_log' ] ) )
1327
  {
1344
  }
1345
 
1346
  /* Should we update options? */
1347
+ if( isset( $_POST[ 'llar_update_dashboard' ] ) ) {
 
 
 
 
 
 
 
 
 
1348
 
1349
  $white_list_ips = ( !empty( $_POST['lla_whitelist_ips'] ) ) ? explode("\n", str_replace("\r", "", stripslashes($_POST['lla_whitelist_ips']) ) ) : array();
1350
 
1394
  }
1395
  $this->update_option('blacklist_usernames', $black_list_usernames );
1396
 
1397
+ $this->sanitize_options();
1398
+
1399
+ $this->show_error( __( 'Settings saved.', 'limit-login-attempts-reloaded' ) );
1400
+ }
1401
+ elseif( isset( $_POST[ 'llar_update_settings' ] ) ) {
1402
+
1403
+ /* Should we support GDPR */
1404
+ if( isset( $_POST[ 'gdpr' ] ) ) {
1405
+
1406
+ $this->update_option( 'gdpr', 1 );
1407
+ } else {
1408
+
1409
+ $this->update_option( 'gdpr', 0 );
1410
+ }
1411
+
1412
+ $this->update_option('allowed_retries', (int)$_POST['allowed_retries'] );
1413
+ $this->update_option('lockout_duration', (int)$_POST['lockout_duration'] * 60 );
1414
+ $this->update_option('valid_duration', (int)$_POST['valid_duration'] * 3600 );
1415
+ $this->update_option('allowed_lockouts', (int)$_POST['allowed_lockouts'] );
1416
+ $this->update_option('long_duration', (int)$_POST['long_duration'] * 3600 );
1417
+ $this->update_option('notify_email_after', (int)$_POST['email_after'] );
1418
+
1419
+ $this->update_option('admin_notify_email', sanitize_email( $_POST['admin_notify_email'] ) );
1420
 
1421
  $trusted_ip_origins = ( !empty( $_POST['lla_trusted_ip_origins'] ) )
1422
+ ? array_map( 'trim', explode( ',', sanitize_text_field( $_POST['lla_trusted_ip_origins'] ) ) )
1423
+ : array();
1424
 
1425
  if( !in_array( 'REMOTE_ADDR', $trusted_ip_origins ) ) {
1426
 
1429
 
1430
  $this->update_option('trusted_ip_origins', $trusted_ip_origins );
1431
 
 
1432
  $notify_methods = array();
1433
  if( isset( $_POST[ 'lockout_notify_log' ] ) ) {
1434
  $notify_methods[] = 'log';
1440
 
1441
  $this->sanitize_options();
1442
 
1443
+ $this->show_error( __( 'Settings saved.', 'limit-login-attempts-reloaded' ) );
1444
+ }
1445
  }
1446
 
1447
  include_once( LLA_PLUGIN_DIR . '/views/options-page.php' );
1559
  </div>
1560
  <div class="llar-review-info">
1561
  <p><?php _e('Hey <strong>Limit Login Attempts Reloaded</strong> user!', 'limit-login-attempts-reloaded'); ?></p>
1562
+ <!--<p><?php _e('A <strong>crazy idea</strong> we wanted to share! What if we put an image from YOU on the <a href="https://wordpress.org/plugins/limit-login-attempts-reloaded/" target="_blank">LLAR page</a>?! (<a href="https://wordpress.org/plugins/hello-dolly/" target="_blank">example</a>) A drawing made by you or your child would cheer people up! Send us your drawing by <a href="mailto:wpchef.me@gmail.com" target="_blank">email</a> and we like it, we\'ll add it in the next release. Let\'s have some fun!', 'limit-login-attempts-reloaded'); ?></p> Also, -->
1563
+ <p><?php _e('We would really like to hear your feedback about the plugin! Please take a couple minutes to write a few words <a href="https://wordpress.org/support/plugin/limit-login-attempts-reloaded/reviews/#new-post" target="_blank">here</a>. Thank you!', 'limit-login-attempts-reloaded'); ?></p>
1564
 
1565
  <ul class="llar-buttons">
1566
  <li><a href="#" class="llar-review-dismiss" data-type="dismiss"><?php _e('Don\'t show again', 'limit-login-attempts-reloaded'); ?></a></li>
1616
 
1617
  if ( !current_user_can('activate_plugins') ) {
1618
 
1619
+ wp_send_json_error(array());
1620
  }
1621
 
1622
  check_ajax_referer('llar-action', 'sec');
1633
  $this->update_option( 'activation_timestamp', strtotime("+1 month") );
1634
  }
1635
 
1636
+ wp_send_json_success(array());
1637
  }
1638
  }
limit-login-attempts-reloaded.php CHANGED
@@ -1,11 +1,11 @@
1
  <?php
2
  /*
3
  Plugin Name: Limit Login Attempts Reloaded
4
- Description: Limit the rate of login attempts, including by way of cookies and for each IP address.
5
  Author: WPChef
6
  Author URI: https://wpchef.org
7
  Text Domain: limit-login-attempts-reloaded
8
- Version: 2.12.3
9
 
10
  Copyright 2008 - 2012 Johan Eenfeldt, 2016 - 2020 WPChef
11
  */
1
  <?php
2
  /*
3
  Plugin Name: Limit Login Attempts Reloaded
4
+ Description: Limit the rate of login attempts for each IP address.
5
  Author: WPChef
6
  Author URI: https://wpchef.org
7
  Text Domain: limit-login-attempts-reloaded
8
+ Version: 2.13.0
9
 
10
  Copyright 2008 - 2012 Johan Eenfeldt, 2016 - 2020 WPChef
11
  */
readme.txt CHANGED
@@ -3,20 +3,19 @@ Contributors: wpchefgadget
3
  Tags: brute force, login, security, GDPR, protection
4
  Requires at least: 3.0
5
  Tested up to: 5.4
6
- Stable tag: 2.12.3
7
 
8
  Reloaded version of the original Limit Login Attempts plugin for Login Protection by a team of WordPress developers. GDPR compliant.
9
 
10
  == Description ==
11
 
12
- Limit the number of login attempts that possible both through the normal login as well as using the auth cookies.
13
- WordPress by default allows unlimited login attempts either through the login page or by sending special cookies. This allows passwords (or hashes) to be cracked via brute-force relatively easily.
14
  Limit Login Attempts Reloaded blocks an Internet address from making further attempts after a specified limit on retries has been reached, making a brute-force attack difficult or impossible.
15
 
16
  Features:
17
 
18
  * Limit the number of retry attempts when logging in (per each IP). This is fully customizable.
19
- * Limit the number of attempts to log in using authorization cookies in the same way.
20
  * Informs the user about the remaining retries or lockout time on the login page.
21
  * Optional logging and optional email notification.
22
  * It is possible to whitelist/blacklist IPs and Usernames.
@@ -51,6 +50,10 @@ Based on the original code from Limit Login Attemps plugin by Johan Eenfeldt.
51
 
52
  == Changelog ==
53
 
 
 
 
 
54
  = 2.12.3 =
55
  * The feedback message is shown for admins only now, and it can also be closed even if the site has issues with AJAX.
56
 
3
  Tags: brute force, login, security, GDPR, protection
4
  Requires at least: 3.0
5
  Tested up to: 5.4
6
+ Stable tag: 2.13.0
7
 
8
  Reloaded version of the original Limit Login Attempts plugin for Login Protection by a team of WordPress developers. GDPR compliant.
9
 
10
  == Description ==
11
 
12
+ Limit the number of login attempts that possible through the normal login as well as XMLRPC, Woocommerce and custom login pages.
13
+ WordPress by default allows unlimited login attempts. This allows passwords to be cracked via brute-force relatively easily.
14
  Limit Login Attempts Reloaded blocks an Internet address from making further attempts after a specified limit on retries has been reached, making a brute-force attack difficult or impossible.
15
 
16
  Features:
17
 
18
  * Limit the number of retry attempts when logging in (per each IP). This is fully customizable.
 
19
  * Informs the user about the remaining retries or lockout time on the login page.
20
  * Optional logging and optional email notification.
21
  * It is possible to whitelist/blacklist IPs and Usernames.
50
 
51
  == Changelog ==
52
 
53
+ = 2.13.0 =
54
+ * Fixed incompatibility with PHP < 5.6.
55
+ * Settings page layout refactored.
56
+
57
  = 2.12.3 =
58
  * The feedback message is shown for admins only now, and it can also be closed even if the site has issues with AJAX.
59
 
views/options-page.php CHANGED
@@ -2,19 +2,18 @@
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>
2
 
3
  if( !defined( 'ABSPATH' ) ) exit();
4
 
5
+ $active_tab = "dashboard";
6
+ if(!empty($_GET["tab"]) && in_array($_GET["tab"], ['dashboard', 'settings', 'debug'])) {
7
 
8
+ $active_tab = $_GET["tab"];
 
 
9
  }
10
  ?>
11
 
12
  <div class="wrap limit-login-page-settings">
13
+ <h2><?php echo __( 'Limit Login Attempts Reloaded', 'limit-login-attempts-reloaded' ); ?></h2>
14
 
15
  <h2 class="nav-tab-wrapper">
16
+ <a href="<?php echo $this->get_options_page_uri(); ?>&tab=dashboard" class="nav-tab <?php if($active_tab == 'dashboard'){echo 'nav-tab-active';} ?> "><?php _e('Dashboard', 'limit-login-attempts-reloaded'); ?></a>
17
  <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>
18
  <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>
19
  </h2>
views/tab-dashboard.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if( !defined( 'ABSPATH' ) ) exit();
4
+
5
+ /**
6
+ * @var $this Limit_Login_Attempts
7
+ */
8
+
9
+ $lockouts_total = $this->get_option( 'lockouts_total' );
10
+ $lockouts = $this->get_option( 'login_lockouts' );
11
+ $lockouts_now = is_array( $lockouts ) ? count( $lockouts ) : 0;
12
+
13
+ $white_list_ips = $this->get_option( 'whitelist' );
14
+ $white_list_ips = ( is_array( $white_list_ips ) && !empty( $white_list_ips ) ) ? implode( "\n", $white_list_ips ) : '';
15
+
16
+ $white_list_usernames = $this->get_option( 'whitelist_usernames' );
17
+ $white_list_usernames = ( is_array( $white_list_usernames ) && !empty( $white_list_usernames ) ) ? implode( "\n", $white_list_usernames ) : '';
18
+
19
+ $black_list_ips = $this->get_option( 'blacklist' );
20
+ $black_list_ips = ( is_array( $black_list_ips ) && !empty( $black_list_ips ) ) ? implode( "\n", $black_list_ips ) : '';
21
+
22
+ $black_list_usernames = $this->get_option( 'blacklist_usernames' );
23
+ $black_list_usernames = ( is_array( $black_list_usernames ) && !empty( $black_list_usernames ) ) ? implode( "\n", $black_list_usernames ) : '';
24
+ ?>
25
+
26
+ <h3><?php echo __( 'Statistics', 'limit-login-attempts-reloaded' ); ?></h3>
27
+ <form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
28
+ <?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
29
+ <table class="form-table">
30
+ <tr>
31
+ <th scope="row" valign="top"><?php echo __( 'Total lockouts', 'limit-login-attempts-reloaded' ); ?></th>
32
+ <td>
33
+ <?php if( $lockouts_total > 0 ) { ?>
34
+ <input class="button" name="reset_total"
35
+ value="<?php echo __( 'Reset Counter', 'limit-login-attempts-reloaded' ); ?>"
36
+ type="submit"/>
37
+ <?php echo sprintf( _n( '%d lockout since last reset', '%d lockouts since last reset', $lockouts_total, 'limit-login-attempts-reloaded' ), $lockouts_total ); ?>
38
+ <?php } else {
39
+ echo __( 'No lockouts yet', 'limit-login-attempts-reloaded' );
40
+ } ?>
41
+ </td>
42
+ </tr>
43
+ <?php if( $lockouts_now > 0 ) { ?>
44
+ <tr>
45
+ <th scope="row"
46
+ valign="top"><?php echo __( 'Active lockouts', 'limit-login-attempts-reloaded' ); ?></th>
47
+ <td>
48
+ <input class="button" name="reset_current"
49
+ value="<?php echo __( 'Restore Lockouts', 'limit-login-attempts-reloaded' ); ?>"
50
+ type="submit"/>
51
+ <?php echo sprintf( __( '%d IP is currently blocked from trying to log in', 'limit-login-attempts-reloaded' ), $lockouts_now ); ?>
52
+ </td>
53
+ </tr>
54
+ <?php } ?>
55
+ </table>
56
+ </form>
57
+ <form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
58
+ <?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
59
+
60
+ <table class="form-table">
61
+ <tr>
62
+ <th scope="row"
63
+ valign="top"><?php echo __( 'Whitelist', 'limit-login-attempts-reloaded' ); ?></th>
64
+ <td>
65
+ <div class="field-col">
66
+ <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>
67
+ <textarea name="lla_whitelist_ips" rows="10" cols="50"><?php echo esc_textarea( $white_list_ips ); ?></textarea>
68
+ </div>
69
+ <div class="field-col">
70
+ <p class="description"><?php _e( 'One Username per line', 'limit-login-attempts-reloaded' ); ?></p>
71
+ <textarea name="lla_whitelist_usernames" rows="10" cols="50"><?php echo esc_textarea( $white_list_usernames ); ?></textarea>
72
+ </div>
73
+ </td>
74
+ </tr>
75
+ <tr>
76
+ <th scope="row"
77
+ valign="top"><?php echo __( 'Blacklist', 'limit-login-attempts-reloaded' ); ?></th>
78
+ <td>
79
+ <div class="field-col">
80
+ <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>
81
+ <textarea name="lla_blacklist_ips" rows="10" cols="50"><?php echo esc_textarea( $black_list_ips ); ?></textarea>
82
+ </div>
83
+ <div class="field-col">
84
+ <p class="description"><?php _e( 'One Username per line', 'limit-login-attempts-reloaded' ); ?></p>
85
+ <textarea name="lla_blacklist_usernames" rows="10" cols="50"><?php echo esc_textarea( $black_list_usernames ); ?></textarea>
86
+ </div>
87
+ </td>
88
+ </tr>
89
+ </table>
90
+ <p class="submit">
91
+ <input class="button button-primary" name="llar_update_dashboard" value="<?php echo __( 'Save Settings', 'limit-login-attempts-reloaded' ); ?>"
92
+ type="submit"/>
93
+ </p>
94
+ </form>
95
+ <?php
96
+ $log = $this->get_option( 'logged' );
97
+ $log = LLA_Helpers::sorted_log_by_date( $log );
98
+
99
+ $lockouts = (array)$this->get_option('lockouts');
100
+
101
+ if( is_array( $log ) && ! empty( $log ) ) { ?>
102
+ <h3><?php echo __( 'Lockout log', 'limit-login-attempts-reloaded' ); ?></h3>
103
+ <form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
104
+ <?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
105
+ <input type="hidden" value="true" name="clear_log"/>
106
+ <p class="submit">
107
+ <input class="button" name="submit" value="<?php echo __( 'Clear Log', 'limit-login-attempts-reloaded' ); ?>"
108
+ type="submit"/>
109
+ </p>
110
+ </form>
111
+
112
+ <div class="limit-login-log">
113
+ <table class="form-table">
114
+ <tr>
115
+ <th scope="col"><?php _e( "Date", 'limit-login-attempts-reloaded' ); ?></th>
116
+ <th scope="col"><?php echo _x( "IP", "Internet address", 'limit-login-attempts-reloaded' ); ?></th>
117
+ <th scope="col"><?php _e( 'Tried to log in as', 'limit-login-attempts-reloaded' ); ?></th>
118
+ <th scope="col"><?php _e( 'Gateway', 'limit-login-attempts-reloaded' ); ?></th>
119
+ <th>
120
+ </tr>
121
+
122
+ <?php foreach ( $log as $date => $user_info ) : ?>
123
+ <tr>
124
+ <td class="limit-login-date"><?php echo date_i18n( 'F d, Y H:i', $date ); ?></td>
125
+ <td class="limit-login-ip">
126
+ <?php echo esc_html( $user_info['ip'] ); ?>
127
+ </td>
128
+ <td class="limit-login-max"><?php echo esc_html( $user_info['username'] ) . ' (' . esc_html( $user_info['counter'] ) .' lockouts)'; ?></td>
129
+ <td class="limit-login-gateway"><?php echo esc_html( $user_info['gateway'] ); ?></td>
130
+ <td>
131
+ <?php if ( !empty( $lockouts[ $user_info['ip'] ] ) && $lockouts[ $user_info['ip'] ] > time() ) : ?>
132
+ <a href="#" class="button limit-login-unlock" data-ip="<?=esc_attr($user_info['ip'])?>" data-username="<?=esc_attr($user_info['username'])?>">Unlock</a>
133
+ <?php elseif ( $user_info['unlocked'] ): ?>
134
+ Unlocked
135
+ <?php endif ?>
136
+ </tr>
137
+ <?php endforeach; ?>
138
+
139
+ </table>
140
+ </div>
141
+ <script>jQuery( function($) {
142
+ $('.limit-login-log .limit-login-unlock').click( function()
143
+ {
144
+ var btn = $(this);
145
+
146
+ if ( btn.hasClass('disabled') )
147
+ return false;
148
+ btn.addClass( 'disabled' );
149
+
150
+ $.post( ajaxurl, {
151
+ action: 'limit-login-unlock',
152
+ sec: '<?=wp_create_nonce('limit-login-unlock') ?>',
153
+ ip: btn.data('ip'),
154
+ username: btn.data('username')
155
+ } )
156
+ .done( function(data) {
157
+ if ( data === true )
158
+ btn.fadeOut( function(){ $(this).parent().text('Unlocked') });
159
+ else
160
+ fail();
161
+ }).fail( fail );
162
+
163
+ function fail() {
164
+ alert('Connection error');
165
+ btn.removeClass('disabled');
166
+ }
167
+
168
+ return false;
169
+ } );
170
+ } )</script>
171
+ <?php
172
+ } /* if showing $log */
173
+ ?>
174
+
views/tab-debug.php CHANGED
@@ -4,7 +4,7 @@ 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;
4
 
5
  $debug_info = '';
6
 
7
+ $ips = $server = array();
8
  foreach ($_SERVER as $key => $value) {
9
 
10
  if(in_array($key, ['SERVER_ADDR'])) continue;
views/tab-settings.php CHANGED
@@ -8,69 +8,23 @@ if( !defined( 'ABSPATH' ) ) exit();
8
 
9
  $gdpr = $this->get_option( 'gdpr' );
10
 
11
- $lockouts_total = $this->get_option( 'lockouts_total' );
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>
@@ -93,44 +47,25 @@ $trusted_ip_origins = ( is_array( $trusted_ip_origins ) && !empty( $trusted_ip_o
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"
@@ -141,127 +76,73 @@ $trusted_ip_origins = ( is_array( $trusted_ip_origins ) && !empty( $trusted_ip_o
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
 
8
 
9
  $gdpr = $this->get_option( 'gdpr' );
10
 
 
 
 
 
11
  $v = explode( ',', $this->get_option( 'lockout_notify' ) );
12
  $log_checked = in_array( 'log', $v ) ? ' checked ' : '';
13
  $email_checked = in_array( 'email', $v ) ? ' checked ' : '';
14
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  $admin_notify_email = $this->get_option( 'admin_notify_email' );
16
  $admin_email_placeholder = (!is_multisite()) ? get_option( 'admin_email' ) : get_site_option( 'admin_email' );
17
 
18
  $trusted_ip_origins = $this->get_option( 'trusted_ip_origins' );
19
  $trusted_ip_origins = ( is_array( $trusted_ip_origins ) && !empty( $trusted_ip_origins ) ) ? implode( ", ", $trusted_ip_origins ) : 'REMOTE_ADDR';
 
 
20
  ?>
21
 
22
+ <h3><?php echo __( 'General Settings', 'limit-login-attempts-reloaded' ); ?></h3>
23
+ <p><?php echo __( 'These settings are independent of the workers (see below).', 'limit-login-attempts-reloaded' ); ?></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  <form action="<?php echo $this->get_options_page_uri(); ?>" method="post">
25
+
26
  <?php wp_nonce_field( 'limit-login-attempts-options' ); ?>
27
+
28
  <?php if ( is_network_admin() ): ?>
29
  <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' ); ?>
30
  <p class="description"><?php esc_html_e('If disabled, the global settings will be forcibly applied to the entire network.') ?></p>
47
  });
48
  </script>
49
  <?php endif ?>
50
+
51
  <table class="form-table">
52
  <tr>
53
  <th scope="row"
54
  valign="top"><?php echo __( 'GDPR compliance', 'limit-login-attempts-reloaded' ); ?></th>
55
  <td>
56
  <input type="checkbox" name="gdpr" value="1" <?php if($gdpr): ?> checked <?php endif; ?>/>
57
+ <?php echo __( 'this makes the plugin <a href="https://gdpr-info.eu/" target="_blank" >GDPR</a> compliant', 'limit-login-attempts-reloaded' ); ?> <br/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  </td>
59
  </tr>
60
  <tr>
61
  <th scope="row"
62
  valign="top"><?php echo __( 'Notify on lockout', 'limit-login-attempts-reloaded' ); ?></th>
63
  <td>
64
+ <?php /*
65
  <input type="checkbox" name="lockout_notify_log" <?php echo $log_checked; ?>
66
  value="log"/> <?php echo __( 'Lockout log', 'limit-login-attempts-reloaded' ); ?><br/>
67
+ */ ?>
68
+
69
  <input type="checkbox" name="lockout_notify_email" <?php echo $email_checked; ?>
70
  value="email"/> <?php echo __( 'Email to', 'limit-login-attempts-reloaded' ); ?>
71
  <input type="email" name="admin_notify_email"
76
  name="email_after"/> <?php echo __( 'lockouts', 'limit-login-attempts-reloaded' ); ?>
77
  </td>
78
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  </table>
 
 
 
 
 
 
 
 
 
 
80
 
81
+ <h3><?php echo __( 'Worker Settings', 'limit-login-attempts-reloaded' ); ?></h3>
82
+ <p><?php echo __( 'The workers absorb the main load caused by brute-force attacks, analyse login attempts and block unwanted visitors. They might provide other service functions as well.', 'limit-login-attempts-reloaded' ); ?></p>
 
 
 
 
 
 
 
 
83
 
84
+ <div id="llar-workers-accordion" class="llar-accordion">
85
+ <h3>Local Worker</h3>
86
+ <div>
87
+ <table class="form-table">
 
 
 
 
 
 
 
88
  <tr>
89
+ <th scope="row" valign="top"><?php echo __( 'Lockout', 'limit-login-attempts-reloaded' ); ?></th>
90
+ <td>
91
+
92
+ <input type="text" size="3" maxlength="4"
93
+ value="<?php echo( $this->get_option( 'allowed_retries' ) ); ?>"
94
+ name="allowed_retries"/> <?php echo __( 'allowed retries', 'limit-login-attempts-reloaded' ); ?>
95
+ <br/>
96
+ <input type="text" size="3" maxlength="4"
97
+ value="<?php echo( $this->get_option( 'lockout_duration' ) / 60 ); ?>"
98
+ name="lockout_duration"/> <?php echo __( 'minutes lockout', 'limit-login-attempts-reloaded' ); ?>
99
+ <br/>
100
+ <input type="text" size="3" maxlength="4"
101
+ value="<?php echo( $this->get_option( 'allowed_lockouts' ) ); ?>"
102
+ name="allowed_lockouts"/> <?php echo __( 'lockouts increase lockout time to', 'limit-login-attempts-reloaded' ); ?>
103
+ <input type="text" size="3" maxlength="4"
104
+ value="<?php echo( $this->get_option( 'long_duration' ) / 3600 ); ?>"
105
+ name="long_duration"/> <?php echo __( 'hours', 'limit-login-attempts-reloaded' ); ?> <br/>
106
+ <input type="text" size="3" maxlength="4"
107
+ value="<?php echo( $this->get_option( 'valid_duration' ) / 3600 ); ?>"
108
+ name="valid_duration"/> <?php echo __( 'hours until retries are reset', 'limit-login-attempts-reloaded' ); ?>
109
  </td>
110
+ </tr>
111
+ <tr>
112
+ <th scope="row"
113
+ valign="top"><?php echo __( 'Trusted IP Origins', 'limit-login-attempts-reloaded' ); ?></th>
114
  <td>
115
+ <div class="field-col">
116
+ <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 ); ?>">
117
+ <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>
118
+ </div>
119
+ </td>
120
  </tr>
121
+ </table>
122
+ </div>
123
+
124
+ <h3>Custom Worker</h3>
125
+ <div>
126
+ <p>
127
+ In the future versions of the plugin you will be able to create your own worker. This will allow you to share White/Black lists and lockout functionality across all your websites. Stay tuned.
128
+ </p>
129
+ </div>
130
  </div>
 
 
 
 
131
 
132
+ <script>
133
+ (function($){
134
+
135
+ $(document).ready(function(){
136
 
137
+ $( "#llar-workers-accordion" ).accordion();
138
+ });
 
 
 
 
 
 
 
 
 
 
139
 
140
+ })(jQuery);
141
+ </script>
 
 
142
 
143
+ <p class="submit">
144
+ <input class="button button-primary" name="llar_update_settings" value="<?php echo __( 'Save Settings', 'limit-login-attempts-reloaded' ); ?>"
145
+ type="submit"/>
146
+ </p>
147
+ </form>
 
148