Restricted Site Access - Version 7.3.3

Version Description

  • 2022-10-31 =
  • Added: Support for IPv6 addresses (props @jeffpaul, @Sidsector9, @cadic).
  • Added: Support for subnet range and pattern formats for IPv4 and IPv6 addresses (props @jeffpaul, @Sidsector9, @cadic).
  • Added: WP VIP Coding Standards (props @peterwilsoncc, @faisal-alvi, @eflorea).
  • Changed: Improved adding IP user experience via settings (props @ankitguptaindia, @dhanendran, @Sidsector9, @dinhtungdu).
  • Changed: Replace Grunt with Webpack (props @cadic, @Sidsector9).
  • Fixed: Missing textdomains to translatable strings (props @pedro-mendonca, @Sidsector9).
Download this release

Release Info

Developer 10up
Plugin Icon 128x128 Restricted Site Access
Version 7.3.3
Comparing to
See all releases

Code changes from version 7.3.2 to 7.3.3

assets/js/admin.min.js DELETED
@@ -1 +0,0 @@
1
- !function(e,s){"use strict";s(".notice").on("click",".notice-dismiss",function(e){e.delegateTarget.getAttribute("data-rsa-notice")&&s.ajax({method:"post",data:{nonce:rsaAdmin.nonce,action:"rsa_notice_dismiss"},url:ajaxurl})})}(window,jQuery),function(e,s){"use strict";({els:{dialog:document.getElementById("rsa-disable-dialog"),userMessage:document.getElementById("rsa-user-message")},variables:{expectedAnswer:rsaAdmin.strings.message.toLowerCase(),disablingURL:null},openDialog(e){e.preventDefault(),s(this.els.dialog).dialog("open")},isExpectedAnswer(){return this.els.userMessage.value.toLowerCase()===this.variables.expectedAnswer},dialogSettings(){const t=this;t.close=function(){s(t.els.dialog).dialog("close"),t.els.userMessage.style.border="1px solid #ddd",t.els.userMessage.value=""},s(this.els.dialog).dialog({dialogClass:"wp-dialog",autoOpen:!1,draggable:!1,width:"auto",modal:!0,resizable:!1,buttons:[{text:rsaAdmin.strings.confirm,click(){t.isExpectedAnswer()?e.location.href=t.variables.disablingURL:t.els.userMessage.style.border="1px solid red"}},{text:rsaAdmin.strings.cancel,click(){t.close()},class:"button-primary"}],open(){s(".ui-widget-overlay").bind("click",function(){t.close()})},create(){s(".ui-dialog-titlebar-close").addClass("ui-button"),s(this).siblings(".ui-dialog-titlebar").hide()}}),this.els.buttons=s(this.els.dialog).dialog("option","buttons")},maybeSubmit(e){switch(e.key){case"Enter":this.els.buttons[0].click()}},bindEvents(){s('[data-slug="restricted-site-access"]').on("click",".deactivate a",this.openDialog.bind(this)),this.els.userMessage&&this.els.userMessage.addEventListener("keyup",this.maybeSubmit.bind(this))},init(){const e=document.getElementById("the-list");e&&(this.variables.disablingURL=e.querySelector('[data-slug="restricted-site-access"] .deactivate a').href),this.bindEvents(),this.dialogSettings()}}).init()}(window,jQuery);
 
assets/js/settings.min.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"use strict";const i=e.document,r={add_btn:"",new_ip:"",ip_list_wrap:"",empty_ip:"",restrict_radio:"",table:"",redirect_choice:"",message_choice:"",page_choice:"",redirect_fields:"",message_field:"",page_field:"",error_field:""};!function(){r.add_btn=t(i.getElementById("addip")),r.new_ip=i.getElementById("newip"),r.new_ip_comment=i.getElementById("newipcomment"),r.ip_list_wrap=i.getElementById("ip_list"),r.empty_ip=t(i.getElementById("ip_list_empty")),r.restrict_radio=i.getElementById("blog-restricted"),r.error_field=i.getElementById("rsa-error-container"),r.table=t(i.getElementById("rsa-send-to-login")).closest("table"),r.redirect_choice=i.getElementById("rsa-redirect-visitor"),r.message_choice=i.getElementById("rsa-display-message"),r.page_choice=i.getElementById("rsa-unblocked-page"),r.redirect_fields=t(i.querySelectorAll(".rsa_redirect_field")).closest("tr"),r.message_field=t(i.getElementById("rsa_message")).closest("tr"),r.page_field=t(i.getElementById("rsa_page")).closest("tr"),r.restrict_radio&&!r.restrict_radio.checked&&r.table.hide(),r.redirect_choice&&!r.redirect_choice.checked&&r.redirect_fields.hide(),r.message_choice&&!r.message_choice.checked&&r.message_field.hide(),r.page_choice&&!r.page_choice.checked&&r.page_field.hide(),t(i.querySelectorAll("#rsa_handle_fields input")).on("change",function(){r.redirect_choice.checked?r.redirect_fields.show():r.redirect_fields.hide(),r.message_choice.checked?r.message_field.show():r.message_field.hide(),r.page_choice.checked?r.page_field.show():r.page_field.hide()}),t(i.querySelectorAll(".option-site-visibility input")).on("change",function(){r.restrict_radio.checked?r.table.show():r.table.hide()}),r.add_btn.on("click",function(){!function(e,c){if(""===t.trim(e))return!1;r.add_btn.attr("disabled","disabled");const d=t(i.querySelectorAll("#ip_list input"));for(let i=0;i<d.length;i++)if(d[i].value===e)return t(d[i]).parent().effect("shake",600),r.add_btn.removeAttr("disabled"),!1;jQuery.post(ajaxurl,{action:"rsa_ip_check",ip_address:e,ip_address_comment:c,nonce:rsaSettings.nonce},function(i){if(!i.success)return t(r.new_ip.parentNode).effect("shake",600),r.add_btn.removeAttr("disabled"),t(r.error_field).text(i.data),!1;t(r.error_field).text("");const d=r.empty_ip.clone().appendTo(r.ip_list_wrap);return d.children("input.ip").val(e),d.children("input.comment").val(c),d.removeAttr("id").slideDown(250),e===r.new_ip.value&&(t(r.new_ip).val(""),t(r.new_ip_comment).val("")),r.add_btn.removeAttr("disabled"),!0})}(r.new_ip.value,r.new_ip_comment.value)});const e=i.getElementById("rsa_myip");null!==e&&t(e).on("click",function(){t(r.new_ip).val(t(this).data("myip"))}),t(r.ip_list_wrap).on("click",".remove_btn",function(){t(this.parentNode).slideUp(250,function(){t(this).remove()})})}()}(window,jQuery);
1
+ !function(e,i){"use strict";const t=e.document,c={add_btn:"",new_ip:"",ip_list_wrap:"",empty_ip:"",restrict_radio:"",table:"",redirect_choice:"",message_choice:"",page_choice:"",redirect_fields:"",message_field:"",page_field:"",error_field:""};!function(){c.add_btn=i(t.getElementById("addip")),c.new_ip=t.getElementById("newip"),c.new_ip_comment=t.getElementById("newipcomment"),c.ip_list_wrap=t.getElementById("ip_list"),c.empty_ip=i(t.getElementById("ip_list_empty")),c.restrict_radio=t.getElementById("blog-restricted"),c.error_field=t.getElementById("rsa-error-container"),c.table=i(t.getElementById("rsa-send-to-login")).closest("table"),c.redirect_choice=t.getElementById("rsa-redirect-visitor"),c.message_choice=t.getElementById("rsa-display-message"),c.page_choice=t.getElementById("rsa-unblocked-page"),c.redirect_fields=i(t.querySelectorAll(".rsa_redirect_field")).closest("tr"),c.message_field=i(t.getElementById("rsa_message")).closest("tr"),c.page_field=i(t.getElementById("rsa_page")).closest("tr"),c.restrict_radio&&!c.restrict_radio.checked&&c.table.hide(),c.redirect_choice&&!c.redirect_choice.checked&&c.redirect_fields.hide(),c.message_choice&&!c.message_choice.checked&&c.message_field.hide(),c.page_choice&&!c.page_choice.checked&&c.page_field.hide(),i(t.querySelectorAll("#rsa_handle_fields input")).on("change",function(){c.redirect_choice.checked?c.redirect_fields.show():c.redirect_fields.hide(),c.message_choice.checked?c.message_field.show():c.message_field.hide(),c.page_choice.checked?c.page_field.show():c.page_field.hide()}),i(t.querySelectorAll(".option-site-visibility input")).on("change",function(){c.restrict_radio.checked?c.table.show():c.table.hide()}),c.add_btn.on("click",function(){c.empty_ip.clone().appendTo(c.ip_list_wrap).removeAttr("id").slideDown(250)}),i(c.ip_list_wrap).on("blur",".ip.code",function(){!function(e,r,s){if(i("#submit").prop("disabled",!0),""===i.trim(e))return void i("#submit").prop("disabled",!1);const d=i(t.querySelectorAll("#ip_list input"));for(let t=0;t<d.length;t++)if(!s.is(d[t])&&d[t].value===e)return i(d[t]).parent().effect("shake",600),void i(s).focus();jQuery.post(ajaxurl,{action:"rsa_ip_check",ip_address:e,ip_address_comment:r,nonce:rsaSettings.nonce},function(e){return e.success?(i(c.error_field).text(""),i("#submit").prop("disabled",!1),!0):(i(s).effect("shake",600).focus(),i(c.error_field).text(e.data),!1)})}(i(this).val(),i(this).next().val(),i(this))});const e=t.getElementById("rsa_myip");null!==e&&i(e).on("click",function(){i(".ip.code:last").val(i(this).data("myip")).blur()}),i(c.ip_list_wrap).on("click",".remove_btn",function(){i(this.parentNode).slideUp(250,function(){i(this).remove()})})}()}(window,jQuery);
assets/js/src/admin.js CHANGED
@@ -1,3 +1,5 @@
 
 
1
  /**
2
  * 10up
3
  * http://10up.com
@@ -31,119 +33,120 @@
31
 
32
  ( function( window, $ ) {
33
  'use strict';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
- const RSADisablePlugin = {
36
- els: {
37
- dialog: document.getElementById( 'rsa-disable-dialog' ),
38
- userMessage: document.getElementById( 'rsa-user-message' ),
39
- },
40
-
41
- variables: {
42
- expectedAnswer: rsaAdmin.strings.message.toLowerCase(),
43
- disablingURL: null,
44
- },
45
-
46
- openDialog( event ) {
47
- event.preventDefault();
48
- $( this.els.dialog ).dialog( 'open' );
49
- },
50
-
51
- isExpectedAnswer() {
52
- const userMessage = this.els.userMessage.value.toLowerCase();
53
-
54
- if ( userMessage === this.variables.expectedAnswer ) {
55
- return true;
56
- }
57
-
58
- return false;
59
- },
60
- dialogSettings() {
61
- const self = this;
62
-
63
- self.close = function() {
64
- $( self.els.dialog ).dialog( 'close' );
65
- self.els.userMessage.style.border = '1px solid #ddd';
66
- self.els.userMessage.value = '';
67
- };
68
-
69
- $( this.els.dialog ).dialog( {
70
- dialogClass: 'wp-dialog',
71
- autoOpen: false,
72
- draggable: false,
73
- width: 'auto',
74
- modal: true,
75
- resizable: false,
76
- buttons: [
77
- {
78
- text: rsaAdmin.strings.confirm,
79
- click() {
80
- if ( self.isExpectedAnswer() ) {
81
- window.location.href =
82
- self.variables.disablingURL;
83
- } else {
84
- self.els.userMessage.style.border =
85
- '1px solid red';
86
- }
87
  },
88
- },
89
- {
90
- text: rsaAdmin.strings.cancel,
91
- click() {
92
- self.close();
 
93
  },
94
- class: 'button-primary',
 
 
 
 
95
  },
96
- ],
97
- open() {
98
- $( '.ui-widget-overlay' ).bind( 'click', function() {
99
- self.close();
100
- } );
101
- },
102
- create() {
103
- $( '.ui-dialog-titlebar-close' ).addClass( 'ui-button' );
104
- $( this ).siblings( '.ui-dialog-titlebar' ).hide();
105
- },
106
- } );
107
-
108
- this.els.buttons = $( this.els.dialog ).dialog(
109
- 'option',
110
- 'buttons'
111
- );
112
- },
113
-
114
- maybeSubmit( event ) {
115
- switch ( event.key ) {
116
- case 'Enter':
117
- this.els.buttons[ 0 ].click();
118
- break;
119
- }
120
- },
121
-
122
- bindEvents() {
123
- $( '[data-slug="restricted-site-access"]' ).on(
124
- 'click',
125
- '.deactivate a',
126
- this.openDialog.bind( this )
127
- );
128
- if ( this.els.userMessage ) {
129
- this.els.userMessage.addEventListener(
130
- 'keyup',
131
- this.maybeSubmit.bind( this )
132
  );
133
- }
134
- },
135
-
136
- init() {
137
- const list = document.getElementById( 'the-list' );
138
- if ( list ) {
139
- this.variables.disablingURL = list.querySelector(
140
- '[data-slug="restricted-site-access"] .deactivate a'
141
- ).href;
142
- }
143
- this.bindEvents();
144
- this.dialogSettings();
145
- },
146
- };
147
-
148
- RSADisablePlugin.init();
 
 
 
 
 
 
149
  }( window, jQuery ) );
1
+ import 'jquery-ui-dialog';
2
+
3
  /**
4
  * 10up
5
  * http://10up.com
33
 
34
  ( function( window, $ ) {
35
  'use strict';
36
+ $( () => {
37
+ const RSADisablePlugin = {
38
+ els: {
39
+ dialog: document.getElementById( 'rsa-disable-dialog' ),
40
+ userMessage: document.getElementById( 'rsa-user-message' ),
41
+ },
42
+
43
+ variables: {
44
+ expectedAnswer: rsaAdmin.strings.message.toLowerCase(),
45
+ disablingURL: null,
46
+ },
47
+
48
+ openDialog( event ) {
49
+ event.preventDefault();
50
+ $( this.els.dialog ).dialog( 'open' );
51
+ },
52
 
53
+ isExpectedAnswer() {
54
+ const userMessage = this.els.userMessage.value.toLowerCase();
55
+
56
+ if ( userMessage === this.variables.expectedAnswer ) {
57
+ return true;
58
+ }
59
+
60
+ return false;
61
+ },
62
+ dialogSettings() {
63
+ const self = this;
64
+
65
+ self.close = function() {
66
+ $( self.els.dialog ).dialog( 'close' );
67
+ self.els.userMessage.style.border = '1px solid #ddd';
68
+ self.els.userMessage.value = '';
69
+ };
70
+
71
+ $( this.els.dialog ).dialog( {
72
+ dialogClass: 'wp-dialog',
73
+ autoOpen: false,
74
+ draggable: false,
75
+ width: 'auto',
76
+ modal: true,
77
+ resizable: false,
78
+ buttons: [
79
+ {
80
+ text: rsaAdmin.strings.confirm,
81
+ click() {
82
+ if ( self.isExpectedAnswer() ) {
83
+ window.location.href =
84
+ self.variables.disablingURL;
85
+ } else {
86
+ self.els.userMessage.style.border =
87
+ '1px solid red';
88
+ }
89
+ },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  },
91
+ {
92
+ text: rsaAdmin.strings.cancel,
93
+ click() {
94
+ self.close();
95
+ },
96
+ class: 'button-primary',
97
  },
98
+ ],
99
+ open() {
100
+ $( '.ui-widget-overlay' ).bind( 'click', function() {
101
+ self.close();
102
+ } );
103
  },
104
+ create() {
105
+ $( '.ui-dialog-titlebar-close' ).addClass( 'ui-button' );
106
+ $( this ).siblings( '.ui-dialog-titlebar' ).hide();
107
+ },
108
+ } );
109
+
110
+ this.els.buttons = $( this.els.dialog ).dialog(
111
+ 'option',
112
+ 'buttons'
113
+ );
114
+ },
115
+
116
+ maybeSubmit( event ) {
117
+ switch ( event.key ) {
118
+ case 'Enter':
119
+ this.els.buttons[ 0 ].click();
120
+ break;
121
+ }
122
+ },
123
+
124
+ bindEvents() {
125
+ $( '[data-slug="restricted-site-access"]' ).on(
126
+ 'click',
127
+ '.deactivate a',
128
+ this.openDialog.bind( this )
 
 
 
 
 
 
 
 
 
 
 
129
  );
130
+ if ( this.els.userMessage ) {
131
+ this.els.userMessage.addEventListener(
132
+ 'keyup',
133
+ this.maybeSubmit.bind( this )
134
+ );
135
+ }
136
+ },
137
+
138
+ init() {
139
+ const list = document.getElementById( 'the-list' );
140
+ if ( list ) {
141
+ this.variables.disablingURL = list.querySelector(
142
+ '[data-slug="restricted-site-access"] .deactivate a'
143
+ ).href;
144
+ }
145
+ this.bindEvents();
146
+ this.dialogSettings();
147
+ },
148
+ };
149
+
150
+ RSADisablePlugin.init();
151
+ } );
152
  }( window, jQuery ) );
assets/js/src/settings.js CHANGED
@@ -1,3 +1,5 @@
 
 
1
  /**
2
  * 10up
3
  * http://10up.com
@@ -26,6 +28,7 @@
26
  message_field: '',
27
  page_field: '',
28
  error_field: '',
 
29
  };
30
 
31
  function init() {
@@ -53,6 +56,7 @@
53
  Cache.page_field = $( document.getElementById( 'rsa_page' ) ).closest(
54
  'tr'
55
  );
 
56
 
57
  if ( Cache.restrict_radio && ! Cache.restrict_radio.checked ) {
58
  Cache.table.hide();
@@ -105,13 +109,20 @@
105
  );
106
 
107
  Cache.add_btn.on( 'click', function() {
108
- addIp( Cache.new_ip.value, Cache.new_ip_comment.value );
 
 
 
 
 
 
 
109
  } );
110
 
111
  const myipBtn = document.getElementById( 'rsa_myip' );
112
  if ( null !== myipBtn ) {
113
  $( myipBtn ).on( 'click', function() {
114
- $( Cache.new_ip ).val( $( this ).data( 'myip' ) );
115
  } );
116
  }
117
 
@@ -122,21 +133,22 @@
122
  } );
123
  }
124
 
125
- function addIp( ip, comment ) {
 
 
 
126
  if ( $.trim( ip ) === '' ) {
127
- return false;
 
128
  }
129
 
130
- const shakeSpeed = 600;
131
-
132
- Cache.add_btn.attr( 'disabled', 'disabled' );
133
  const ipList = $( document.querySelectorAll( '#ip_list input' ) );
134
 
135
  for ( let i = 0; i < ipList.length; i++ ) {
136
- if ( ipList[ i ].value === ip ) {
137
  $( ipList[ i ] ).parent().effect( 'shake', shakeSpeed );
138
- Cache.add_btn.removeAttr( 'disabled' );
139
- return false;
140
  }
141
  }
142
 
@@ -150,30 +162,21 @@
150
  },
151
  function( response ) {
152
  if ( ! response.success ) {
153
- $( Cache.new_ip.parentNode ).effect( 'shake', shakeSpeed );
154
- Cache.add_btn.removeAttr( 'disabled' );
155
  $( Cache.error_field ).text( response.data );
156
  return false;
157
  }
158
 
159
  $( Cache.error_field ).text( '' );
160
- const newIp = Cache.empty_ip
161
- .clone()
162
- .appendTo( Cache.ip_list_wrap );
163
- newIp.children( 'input.ip' ).val( ip );
164
- newIp.children( 'input.comment' ).val( comment );
165
- newIp.removeAttr( 'id' ).slideDown( 250 );
166
-
167
- if ( ip === Cache.new_ip.value ) {
168
- $( Cache.new_ip ).val( '' );
169
- $( Cache.new_ip_comment ).val( '' );
170
- }
171
- Cache.add_btn.removeAttr( 'disabled' );
172
 
173
  return true;
174
  }
175
  );
176
  }
177
 
178
- init();
 
 
179
  }( window, jQuery ) );
1
+ import 'jquery-effects-shake';
2
+
3
  /**
4
  * 10up
5
  * http://10up.com
28
  message_field: '',
29
  page_field: '',
30
  error_field: '',
31
+ submit_btn: '',
32
  };
33
 
34
  function init() {
56
  Cache.page_field = $( document.getElementById( 'rsa_page' ) ).closest(
57
  'tr'
58
  );
59
+ Cache.submit_btn = $( '#submit' );
60
 
61
  if ( Cache.restrict_radio && ! Cache.restrict_radio.checked ) {
62
  Cache.table.hide();
109
  );
110
 
111
  Cache.add_btn.on( 'click', function() {
112
+ const newIp = Cache.empty_ip
113
+ .clone()
114
+ .appendTo( Cache.ip_list_wrap );
115
+ newIp.removeAttr( 'id' ).slideDown( 250 );
116
+ } );
117
+
118
+ $( Cache.ip_list_wrap ).on( 'blur', '.ip.code', function() {
119
+ addIp( $( this ).val(), $( this ).next().val(), $( this ) );
120
  } );
121
 
122
  const myipBtn = document.getElementById( 'rsa_myip' );
123
  if ( null !== myipBtn ) {
124
  $( myipBtn ).on( 'click', function() {
125
+ $( '.ip.code:last' ).val( $( this ).data( 'myip' ) ).blur();
126
  } );
127
  }
128
 
133
  } );
134
  }
135
 
136
+ function addIp( ip, comment, obj ) {
137
+ const shakeSpeed = 600;
138
+ Cache.submit_btn.prop( 'disabled', true );
139
+
140
  if ( $.trim( ip ) === '' ) {
141
+ Cache.submit_btn.prop( 'disabled', false );
142
+ return;
143
  }
144
 
 
 
 
145
  const ipList = $( document.querySelectorAll( '#ip_list input' ) );
146
 
147
  for ( let i = 0; i < ipList.length; i++ ) {
148
+ if ( ! obj.is( ipList[ i ] ) && ipList[ i ].value === ip ) {
149
  $( ipList[ i ] ).parent().effect( 'shake', shakeSpeed );
150
+ $( obj ).focus();
151
+ return;
152
  }
153
  }
154
 
162
  },
163
  function( response ) {
164
  if ( ! response.success ) {
165
+ $( obj ).effect( 'shake', shakeSpeed ).focus();
 
166
  $( Cache.error_field ).text( response.data );
167
  return false;
168
  }
169
 
170
  $( Cache.error_field ).text( '' );
171
+
172
+ Cache.submit_btn.prop( 'disabled', false );
 
 
 
 
 
 
 
 
 
 
173
 
174
  return true;
175
  }
176
  );
177
  }
178
 
179
+ $( function() {
180
+ init();
181
+ } );
182
  }( window, jQuery ) );
phpcs.xml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Example Project" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd">
3
+
4
+ <description>A custom set of rules to check for the Restricted Site Access project.</description>
5
+
6
+ <arg name="extensions" value="php"/>
7
+
8
+ <!-- Exclude the Composer Vendor directory. -->
9
+ <exclude-pattern>/vendor/*</exclude-pattern>
10
+
11
+ <!-- Exclude the Node Modules directory. -->
12
+ <exclude-pattern>/node_modules/*</exclude-pattern>
13
+
14
+ <!-- Exclude minified Javascript files. -->
15
+ <exclude-pattern>*.min.js</exclude-pattern>
16
+
17
+ <!-- Exclude the assets directory. -->
18
+ <exclude-pattern>assets</exclude-pattern>
19
+
20
+ <exclude-pattern>tests/php/bootstrap.php</exclude-pattern>
21
+
22
+ <!-- Let's also check that everything is properly documented. -->
23
+ <rule ref="WordPress">
24
+ <exclude name="WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase" />
25
+ </rule>
26
+
27
+ <rule ref="Squiz.Commenting.FileComment.Missing">
28
+ <exclude-pattern>tests</exclude-pattern>
29
+ </rule>
30
+
31
+ <rule ref="Squiz.Commenting.ClassComment.Missing">
32
+ <exclude-pattern>tests</exclude-pattern>
33
+ </rule>
34
+
35
+ <rule ref="Squiz.Commenting.FunctionComment.Missing">
36
+ <exclude-pattern>tests</exclude-pattern>
37
+ </rule>
38
+
39
+ <!-- Add in some extra rules from other standards. -->
40
+ <config name="minimum_supported_wp_version" value="5.7"/>
41
+
42
+ </ruleset>
phpcs.xml.dist ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset name="Project Rules">
3
+
4
+ <!-- Only scan PHP files. -->
5
+ <arg name="extensions" value="php"/>
6
+
7
+ <!-- Show sniff codes in all reports. -->
8
+ <arg value="ps"/>
9
+
10
+ <file>.</file>
11
+
12
+ <exclude-pattern type="relative">^tests/*</exclude-pattern>
13
+ <exclude-pattern type="relative">^vendor/*</exclude-pattern>
14
+
15
+ <rule ref="10up-Default" />
16
+ <rule ref="WordPress-VIP-Go">
17
+ <!--
18
+ This plugin is designed to run on both standard WordPress installs
19
+ and on WordPress VIP installs. As such the WP-CLI command included
20
+ needs to be able to run without the WordPress VIP mu-plugins.
21
+ -->
22
+ <exclude name="WordPressVIPMinimum.Classes.RestrictedExtendClasses.wp_cli" />
23
+ </rule>
24
+ </ruleset>
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: 10up, jakemgold, rcbth, thinkoomph, tlovett1, jeffpaul, nomno
3
  Donate link: https://10up.com/plugins/restricted-site-access-wordpress/
4
  Tags: privacy, restricted, restrict, privacy, limited, permissions, security, block
5
  Requires at least: 5.7
6
- Tested up to: 6.0
7
- Stable tag: 7.3.2
8
  Requires PHP: 7.4
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -198,7 +198,17 @@ Please note that setting `RSA_FORCE_RESTRICTION` will override `RSA_FORBID_RESTR
198
 
199
  == Changelog ==
200
 
 
 
 
 
 
 
 
 
201
  = 7.3.2 - 2022-08-29 =
 
 
202
  * **Added:** New filter - `rsa_get_client_ip_address_filter_flags` to modify the range of accepted IP addresses.
203
  * **Changed:** Avoid disjointed plugin settings (props [@helen](https://github.com/helen), [@peterwilsoncc](https://github.com/peterwilsoncc), [@Sidsector9](https://github.com/Sidsector9)).
204
  * **Changed:** Bump minimum WordPress version from 5.0 to 5.7 (props [@vikrampm1](https://github.com/vikrampm1), [@Sidsector9](https://github.com/Sidsector9), [@faisal-alvi](https://github.com/faisal-alvi)).
3
  Donate link: https://10up.com/plugins/restricted-site-access-wordpress/
4
  Tags: privacy, restricted, restrict, privacy, limited, permissions, security, block
5
  Requires at least: 5.7
6
+ Tested up to: 6.1
7
+ Stable tag: 7.3.3
8
  Requires PHP: 7.4
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
198
 
199
  == Changelog ==
200
 
201
+ = 7.3.3 - 2022-10-31 =
202
+ * **Added:** Support for IPv6 addresses (props [@jeffpaul](https://github.com/jeffpaul), [@Sidsector9](https://github.com/Sidsector9), [@cadic](https://github.com/cadic)).
203
+ * **Added:** Support for subnet range and pattern formats for IPv4 and IPv6 addresses (props [@jeffpaul](https://github.com/jeffpaul), [@Sidsector9](https://github.com/Sidsector9), [@cadic](https://github.com/cadic)).
204
+ * **Added:** WP VIP Coding Standards (props [@peterwilsoncc](https://github.com/peterwilsoncc), [@faisal-alvi](https://github.com/faisal-alvi), [@eflorea](https://github.com/eflorea)).
205
+ * **Changed:** Improved adding IP user experience via settings (props [@ankitguptaindia](https://github.com/ankitguptaindia), [@dhanendran](https://github.com/dhanendran), [@Sidsector9](https://github.com/Sidsector9), [@dinhtungdu](https://github.com/dinhtungdu)).
206
+ * **Changed:** Replace Grunt with Webpack (props [@cadic](https://github.com/cadic), [@Sidsector9](https://github.com/Sidsector9)).
207
+ * **Fixed:** Missing textdomains to translatable strings (props [@pedro-mendonca](https://github.com/pedro-mendonca), [@Sidsector9](https://github.com/Sidsector9)).
208
+
209
  = 7.3.2 - 2022-08-29 =
210
+ **Note:** this release contains two new filters that we recommend using to further secure your site. See the [readme](https://wordpress.org/plugins/restricted-site-access/#how%20secure%20is%20this%20plug-in%3F) for full details.
211
+
212
  * **Added:** New filter - `rsa_get_client_ip_address_filter_flags` to modify the range of accepted IP addresses.
213
  * **Changed:** Avoid disjointed plugin settings (props [@helen](https://github.com/helen), [@peterwilsoncc](https://github.com/peterwilsoncc), [@Sidsector9](https://github.com/Sidsector9)).
214
  * **Changed:** Bump minimum WordPress version from 5.0 to 5.7 (props [@vikrampm1](https://github.com/vikrampm1), [@Sidsector9](https://github.com/Sidsector9), [@faisal-alvi](https://github.com/faisal-alvi)).
restricted_site_access.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Restricted Site Access
4
  * Plugin URI: https://10up.com/plugins/restricted-site-access-wordpress/
5
  * Description: <strong>Limit access your site</strong> to visitors who are logged in or accessing the site from a set of specific IP addresses. Send restricted visitors to the log in page, redirect them, or display a message or page. <strong>Powerful control over redirection</strong>, including <strong>SEO friendly redirect headers</strong>. Great solution for Extranets, publicly hosted Intranets, or parallel development sites.
6
- * Version: 7.3.2
7
  * Requires at least: 5.7
8
  * Requires PHP: 7.4
9
  * Author: Jake Goldman, 10up, Oomph
@@ -13,6 +13,8 @@
13
  * Text Domain: restricted-site-access
14
  */
15
 
 
 
16
  define( 'RSA_VERSION', '7.3.2' );
17
 
18
  /**
@@ -303,7 +305,7 @@ class Restricted_Site_Access {
303
  /**
304
  * Redirects restricted requests.
305
  *
306
- * @param array $wp WordPress request.
307
  * @codeCoverageIgnore
308
  */
309
  public static function restrict_access( $wp ) {
@@ -341,7 +343,7 @@ class Restricted_Site_Access {
341
  /**
342
  * Determine whether page should be restricted at point of request.
343
  *
344
- * @param array $wp WordPress The main WP request.
345
  * @return array List of URL and code, otherwise empty.
346
  */
347
  public static function restrict_access_check( $wp ) {
@@ -371,8 +373,8 @@ class Restricted_Site_Access {
371
  $remote_ip = self::get_client_ip_address();
372
 
373
  // iterate through the allow list.
374
- foreach ( $allowed_ips as $line ) {
375
- if ( $remote_ip && self::ip_in_range( $remote_ip, $line ) ) {
376
 
377
  /**
378
  * Fires when an ip address match occurs.
@@ -383,10 +385,10 @@ class Restricted_Site_Access {
383
  *
384
  * @since 6.0.2
385
  *
386
- * @param string $remote_ip The remote IP address being checked.
387
- * @param string $line The matched masked IP address.
388
  */
389
- do_action( 'restrict_site_access_ip_match', $remote_ip, $line );
390
  return;
391
  }
392
  }
@@ -748,16 +750,17 @@ class Restricted_Site_Access {
748
  return;
749
  }
750
 
751
- $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
752
- $folder = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'src/' : '';
 
 
 
 
 
 
 
753
 
754
- wp_enqueue_script(
755
- 'rsa-settings',
756
- plugin_dir_url( __FILE__ ) . 'assets/js/' . $folder . 'settings' . $min . '.js',
757
- array( 'jquery-effects-shake' ),
758
- RSA_VERSION,
759
- true
760
- );
761
 
762
  wp_localize_script(
763
  'rsa-settings',
@@ -778,16 +781,17 @@ class Restricted_Site_Access {
778
  return;
779
  }
780
 
781
- $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
782
- $folder = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? 'src/' : '';
 
 
 
 
 
 
 
783
 
784
- wp_enqueue_script(
785
- 'rsa-admin',
786
- plugin_dir_url( __FILE__ ) . 'assets/js/' . $folder . 'admin' . $min . '.js',
787
- array( 'jquery', 'jquery-ui-dialog' ),
788
- RSA_VERSION,
789
- true
790
- );
791
 
792
  wp_localize_script(
793
  'rsa-admin',
@@ -1109,8 +1113,12 @@ class Restricted_Site_Access {
1109
  public static function settings_field_allowed() {
1110
  ?>
1111
  <div class="hide-if-no-js rsa-ip-addresses-field-wrapper">
 
 
 
 
 
1112
  <div id="ip_list">
1113
- <div id="ip_list_empty" style="display: none;"><input type="text" name="rsa_options[allowed][]" class="ip code" value="" readonly="true" size="20" /> <input type="text" name="rsa_options[comment][]" value="" class="comment" size="20" /> <a href="#remove" class="remove_btn"><?php echo esc_html( _x( 'Remove', 'remove IP address action', 'restricted-site-access' ) ); ?></a></div>
1114
  <?php
1115
  $ips = (array) self::$rsa_options['allowed'];
1116
  $comments = isset( self::$rsa_options['comment'] ) ? (array) self::$rsa_options['comment'] : array();
@@ -1124,15 +1132,23 @@ class Restricted_Site_Access {
1124
 
1125
  foreach ( $ips as $key => $ip ) {
1126
  if ( ! empty( $ip ) ) {
1127
- echo '<div class="rsa_unrestricted_ip_row"><input type="text" name="rsa_options[allowed][]" value="' . esc_attr( $ip ) . '" class="ip code" readonly="true" size="20" /> <input type="text" name="rsa_options[comment][]" value="' . ( isset( $comments[ $key ] ) ? esc_attr( wp_unslash( $comments[ $key ] ) ) : '' ) . '" size="20" /> <a href="#remove" class="remove_btn">' . esc_html_x( 'Remove', 'remove IP address action', 'restricted-site-access' ) . '</a></div>';
 
 
 
 
1128
  }
1129
  }
1130
  ?>
 
 
 
 
 
1131
  </div>
1132
  <div id="rsa_add_new_ip_fields">
1133
- <input type="text" name="newip" id="newip" class="ip code" placeholder="<?php esc_attr_e( 'IP Address or Range' ); ?>" size="20" />
1134
- <input type="text" name="newipcomment" id="newipcomment" placeholder="<?php esc_attr_e( 'Identify this entry' ); ?>" size="20" /> <input class="button" type="button" id="addip" value="<?php esc_attr_e( 'Add' ); ?>" />
1135
- <p class="description"><label for="newip"><?php esc_html_e( 'Enter a single IP address or a range using a subnet prefix', 'restricted-site-access' ); ?></label></p>
1136
  <?php if ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) : ?>
1137
  <input class="button" type="button" id="rsa_myip" value="<?php esc_attr_e( 'Add My Current IP Address', 'restricted-site-access' ); ?>" style="margin-top: 5px;" data-myip="<?php echo esc_attr( self::get_client_ip_address() ); ?>" /><br />
1138
  <?php endif; ?>
@@ -1150,7 +1166,7 @@ class Restricted_Site_Access {
1150
  <ul class="ul-disc">
1151
  <?php
1152
  foreach ( $config_ips as $ip ) {
1153
- echo '<li><code>' . esc_attr( $ip ) . '</code></li>';
1154
  }
1155
  ?>
1156
  </ul>
@@ -1293,7 +1309,13 @@ class Restricted_Site_Access {
1293
  exit;
1294
  }
1295
 
1296
- if ( empty( $_POST['ip_address'] ) || ! self::is_ip( stripslashes( sanitize_text_field( wp_unslash( $_POST['ip_address'] ) ) ) ) ) {
 
 
 
 
 
 
1297
  wp_send_json_error( __( 'The IP entered is invalid.', 'restricted-site-access' ) );
1298
  }
1299
 
@@ -1308,34 +1330,9 @@ class Restricted_Site_Access {
1308
  * @return bool True if its a valid IP address.
1309
  */
1310
  public static function is_ip( $ip_address ) {
1311
- // very basic validation of ranges.
1312
- if ( strpos( $ip_address, '/' ) ) {
1313
- $ip_parts = explode( '/', $ip_address );
1314
- if ( empty( $ip_parts[1] ) || ! is_numeric( $ip_parts[1] ) || strlen( $ip_parts[1] ) > 3 ) {
1315
- return false;
1316
- }
1317
-
1318
- $ip_address = $ip_parts[0];
1319
-
1320
- $protocol = self::get_ip_protocol( $ip_address );
1321
-
1322
- if ( 'IPv4' === $protocol && (int)$ip_parts[1] > 32 ) {
1323
- /**
1324
- * Return if the prefix length is greater than 32.
1325
- * IPv4 can use maximum of 32 bits for address space.
1326
- */
1327
- return false;
1328
- } else if ( 'IPv6' === $protocol && (int)$ip_parts[1] > 128 ) {
1329
- /**
1330
- * Return if the prefix length is greater than 128.
1331
- * IPv6 can use maximum of 128 bits for address space.
1332
- */
1333
- return false;
1334
- }
1335
- }
1336
 
1337
- // confirm IP part is a valid IPv6 or IPv4 IP.
1338
- if ( empty( $ip_address ) || ! inet_pton( stripslashes( $ip_address ) ) ) {
1339
  return false;
1340
  }
1341
 
@@ -1511,16 +1508,21 @@ class Restricted_Site_Access {
1511
  * @return boolean true if the ip is in this range / false if not.
1512
  */
1513
  public static function ip_in_range( $ip, $range ) {
1514
- if ( strpos( $range, '/' ) === false ) {
1515
- $range .= '/32';
1516
- }
1517
- // $range is in IP/CIDR format eg 127.0.0.1/24
1518
- list( $range, $netmask ) = explode( '/', $range, 2 );
1519
- $range_decimal = ip2long( $range );
1520
- $ip_decimal = ip2long( $ip );
1521
- $wildcard_decimal = pow( 2, ( 32 - $netmask ) ) - 1;
1522
- $netmask_decimal = ~ $wildcard_decimal;
1523
- return ( ( $ip_decimal & $netmask_decimal ) === ( $range_decimal & $netmask_decimal ) );
 
 
 
 
 
1524
  }
1525
 
1526
  /**
@@ -1530,6 +1532,7 @@ class Restricted_Site_Access {
1530
  */
1531
  public static function get_client_ip_address() {
1532
  // REMOTE_ADDR IP address.
 
1533
  $remote_addr_header_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : false;
1534
 
1535
  // Return if REMOTE_ADDR is not set.
@@ -1638,7 +1641,7 @@ class Restricted_Site_Access {
1638
  }
1639
 
1640
  /**
1641
- * Get IPs programmatically
1642
  *
1643
  * @param bool $include_config Whether to include the config file IPs. Default true.
1644
  * @param bool $include_labels Whether to include the comments. Default false.
@@ -1913,32 +1916,3 @@ function restricted_site_access_uninstall() {
1913
  }
1914
 
1915
  register_uninstall_hook( __FILE__, 'restricted_site_access_uninstall' );
1916
-
1917
- if ( ! function_exists( 'inet_pton' ) ) :
1918
-
1919
- /**
1920
- * Inet_pton is not included in PHP < 5.3 on Windows (WP requires PHP 5.2).
1921
- *
1922
- * @param string $ip IP Address.
1923
- *
1924
- * @return array|string
1925
- *
1926
- * @codeCoverageIgnore
1927
- */
1928
- function inet_pton( $ip ) {
1929
- if ( strpos( $ip, '.' ) !== false ) {
1930
- // ipv4.
1931
- $ip = pack( 'N', ip2long( $ip ) );
1932
- } elseif ( strpos( $ip, ':' ) !== false ) {
1933
- // ipv6.
1934
- $ip = explode( ':', $ip );
1935
- $res = str_pad( '', ( 4 * ( 8 - count( $ip ) ) ), '0000', STR_PAD_LEFT );
1936
- foreach ( $ip as $seg ) {
1937
- $res .= str_pad( $seg, 4, '0', STR_PAD_LEFT );
1938
- }
1939
- $ip = pack( 'H' . strlen( $res ), $res );
1940
- }
1941
- return $ip;
1942
- }
1943
-
1944
- endif;
3
  * Plugin Name: Restricted Site Access
4
  * Plugin URI: https://10up.com/plugins/restricted-site-access-wordpress/
5
  * Description: <strong>Limit access your site</strong> to visitors who are logged in or accessing the site from a set of specific IP addresses. Send restricted visitors to the log in page, redirect them, or display a message or page. <strong>Powerful control over redirection</strong>, including <strong>SEO friendly redirect headers</strong>. Great solution for Extranets, publicly hosted Intranets, or parallel development sites.
6
+ * Version: 7.3.3
7
  * Requires at least: 5.7
8
  * Requires PHP: 7.4
9
  * Author: Jake Goldman, 10up, Oomph
13
  * Text Domain: restricted-site-access
14
  */
15
 
16
+ require_once 'vendor/autoload.php';
17
+
18
  define( 'RSA_VERSION', '7.3.2' );
19
 
20
  /**
305
  /**
306
  * Redirects restricted requests.
307
  *
308
+ * @param \WP $wp WordPress request.
309
  * @codeCoverageIgnore
310
  */
311
  public static function restrict_access( $wp ) {
343
  /**
344
  * Determine whether page should be restricted at point of request.
345
  *
346
+ * @param \WP $wp WordPress The main WP request.
347
  * @return array List of URL and code, otherwise empty.
348
  */
349
  public static function restrict_access_check( $wp ) {
373
  $remote_ip = self::get_client_ip_address();
374
 
375
  // iterate through the allow list.
376
+ foreach ( $allowed_ips as $allowed_ip ) {
377
+ if ( $remote_ip && self::ip_in_range( $remote_ip, $allowed_ip ) ) {
378
 
379
  /**
380
  * Fires when an ip address match occurs.
385
  *
386
  * @since 6.0.2
387
  *
388
+ * @param string $remote_ip The remote IP address being checked.
389
+ * @param string $allowed_ip The matched masked IP address.
390
  */
391
+ do_action( 'restrict_site_access_ip_match', $remote_ip, $allowed_ip );
392
  return;
393
  }
394
  }
750
  return;
751
  }
752
 
753
+ $script_path = 'assets/js/build/settings.min.js';
754
+ $script_asset_path = plugin_dir_path( __FILE__ ) . 'assets/js/build/settings.min.asset.php';
755
+ $script_asset = file_exists( $script_asset_path )
756
+ ? require $script_asset_path
757
+ : array(
758
+ 'dependencies' => array(),
759
+ 'version' => filemtime( $script_path ),
760
+ );
761
+ $script_url = plugins_url( $script_path, __FILE__ );
762
 
763
+ wp_enqueue_script( 'rsa-settings', $script_url, $script_asset['dependencies'], $script_asset['version'], true );
 
 
 
 
 
 
764
 
765
  wp_localize_script(
766
  'rsa-settings',
781
  return;
782
  }
783
 
784
+ $script_path = 'assets/js/build/admin.min.js';
785
+ $script_asset_path = plugin_dir_path( __FILE__ ) . 'assets/js/build/admin.min.asset.php';
786
+ $script_asset = file_exists( $script_asset_path )
787
+ ? require $script_asset_path
788
+ : array(
789
+ 'dependencies' => array(),
790
+ 'version' => filemtime( $script_path ),
791
+ );
792
+ $script_url = plugins_url( $script_path, __FILE__ );
793
 
794
+ wp_enqueue_script( 'rsa-admin', $script_url, $script_asset['dependencies'], $script_asset['version'], true );
 
 
 
 
 
 
795
 
796
  wp_localize_script(
797
  'rsa-admin',
1113
  public static function settings_field_allowed() {
1114
  ?>
1115
  <div class="hide-if-no-js rsa-ip-addresses-field-wrapper">
1116
+ <div id="ip_list_empty" style="display: none;" class="rsa_unrestricted_ip_row">
1117
+ <input type="text" name="rsa_options[allowed][]" class="ip code" value="" size="20" placeholder="<?php esc_attr_e( 'IP Address or Range' ); ?>" />
1118
+ <input type="text" name="rsa_options[comment][]" value="" class="newipcomment" size="20" placeholder="<?php esc_attr_e( 'Identify this entry' ); ?>" />
1119
+ <a href="#remove" class="remove_btn"><?php echo esc_html( _x( 'Remove', 'remove IP address action', 'restricted-site-access' ) ); ?></a>
1120
+ </div>
1121
  <div id="ip_list">
 
1122
  <?php
1123
  $ips = (array) self::$rsa_options['allowed'];
1124
  $comments = isset( self::$rsa_options['comment'] ) ? (array) self::$rsa_options['comment'] : array();
1132
 
1133
  foreach ( $ips as $key => $ip ) {
1134
  if ( ! empty( $ip ) ) {
1135
+ echo '<div class="rsa_unrestricted_ip_row">
1136
+ <input type="text" name="rsa_options[allowed][]" value="' . esc_attr( $ip ) . '" class="ip code" size="20" placeholder="' . esc_attr__( 'IP Address or Range' ) . '" />
1137
+ <input type="text" name="rsa_options[comment][]" value="' . ( isset( $comments[ $key ] ) ? esc_attr( wp_unslash( $comments[ $key ] ) ) : '' ) . '" class="newipcomment" size="20" placeholder="' . esc_attr__( 'Identify this entry' ) . '" />
1138
+ <a href="#remove" class="remove_btn">' . esc_html_x( 'Remove', 'remove IP address action', 'restricted-site-access' ) . '</a>
1139
+ </div>';
1140
  }
1141
  }
1142
  ?>
1143
+ <div class="rsa_unrestricted_ip_row">
1144
+ <input type="text" name="rsa_options[allowed][]" class="ip code" placeholder="<?php esc_attr_e( 'IP Address or Range' ); ?>" size="20" />
1145
+ <input type="text" name="rsa_options[comment][]" class="newipcomment" placeholder="<?php esc_attr_e( 'Identify this entry' ); ?>" size="20" />
1146
+ <a href="#remove" class="remove_btn"><?php echo esc_html( _x( 'Remove', 'remove IP address action', 'restricted-site-access' ) ); ?></a>
1147
+ </div>
1148
  </div>
1149
  <div id="rsa_add_new_ip_fields">
1150
+ <p class="description"><label><?php esc_html_e( 'Enter a single IP address or a range using a subnet prefix', 'restricted-site-access' ); ?></label></p>
1151
+ <input class="button" type="button" id="addip" value="<?php esc_attr_e( 'Add new IP' ); ?>" style="margin-top: 5px;" />
 
1152
  <?php if ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) : ?>
1153
  <input class="button" type="button" id="rsa_myip" value="<?php esc_attr_e( 'Add My Current IP Address', 'restricted-site-access' ); ?>" style="margin-top: 5px;" data-myip="<?php echo esc_attr( self::get_client_ip_address() ); ?>" /><br />
1154
  <?php endif; ?>
1166
  <ul class="ul-disc">
1167
  <?php
1168
  foreach ( $config_ips as $ip ) {
1169
+ echo '<li><code>' . esc_html( $ip ) . '</code></li>';
1170
  }
1171
  ?>
1172
  </ul>
1309
  exit;
1310
  }
1311
 
1312
+ if ( ! isset( $_POST['ip_address'] ) ) {
1313
+ wp_send_json_error( __( 'IP cannot be blank.', 'restricted-site-access' ) );
1314
+ }
1315
+
1316
+ $input_ip = stripslashes( sanitize_text_field( wp_unslash( $_POST['ip_address'] ) ) );
1317
+
1318
+ if ( empty( $_POST['ip_address'] ) || ! self::is_ip( $input_ip ) ) {
1319
  wp_send_json_error( __( 'The IP entered is invalid.', 'restricted-site-access' ) );
1320
  }
1321
 
1330
  * @return bool True if its a valid IP address.
1331
  */
1332
  public static function is_ip( $ip_address ) {
1333
+ $address = \IPLib\Factory::parseRangeString( $ip_address );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1334
 
1335
+ if ( is_null( $address ) ) {
 
1336
  return false;
1337
  }
1338
 
1508
  * @return boolean true if the ip is in this range / false if not.
1509
  */
1510
  public static function ip_in_range( $ip, $range ) {
1511
+ $in_range = false;
1512
+ $parsed_range = \IPLib\Factory::parseRangeString( $range );
1513
+ $user_address = \IPLib\Factory::parseAddressString( $ip );
1514
+
1515
+ if ( empty( $user_address ) ) {
1516
+ return false;
1517
+ }
1518
+
1519
+ if ( $parsed_range instanceof \IPLib\Range\Single ) {
1520
+ $in_range = $user_address->matches( $parsed_range );
1521
+ } elseif ( $parsed_range instanceof \IPLib\Range\Subnet || $parsed_range instanceof \IPLib\Range\Pattern ) {
1522
+ $in_range = $parsed_range->contains( $user_address );
1523
+ }
1524
+
1525
+ return $in_range;
1526
  }
1527
 
1528
  /**
1532
  */
1533
  public static function get_client_ip_address() {
1534
  // REMOTE_ADDR IP address.
1535
+ // phpcs:ignore WordPressVIPMinimum.Variables.ServerVariables.UserControlledHeaders, WordPressVIPMinimum.Variables.RestrictedVariables.cache_constraints___SERVER__REMOTE_ADDR__
1536
  $remote_addr_header_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : false;
1537
 
1538
  // Return if REMOTE_ADDR is not set.
1641
  }
1642
 
1643
  /**
1644
+ * Get whitelisted IPs programmatically from the database.
1645
  *
1646
  * @param bool $include_config Whether to include the config file IPs. Default true.
1647
  * @param bool $include_labels Whether to include the comments. Default false.
1916
  }
1917
 
1918
  register_uninstall_hook( __FILE__, 'restricted_site_access_uninstall' );