| 1 |
<?php |
| 2 |
/** |
| 3 |
* NETSENSAI Shield |
| 4 |
* |
| 5 |
* Plugin Name: NETSENSAI Shield |
| 6 |
* Plugin URI: https://www.netsensai.pl/store/ |
| 7 |
* Description: NETSENSAI Shield is a security plugin designed to enhance WordPress site protection by offering essential security features based on best practice principles. |
| 8 |
* Version: 1.6.1 |
| 9 |
* Author: Rafał Gierlicki |
| 10 |
* Author URI: https://www.netsensai.pl |
| 11 |
* Text Domain: netsensai-shield |
| 12 |
* Contributors: netsensai |
| 13 |
* License: GPLv2 or later |
| 14 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html |
| 15 |
*/ |
| 16 |
|
| 17 |
// Exit if accessed directly. |
| 18 |
if ( ! defined( 'ABSPATH' ) ) { |
| 19 |
exit; |
| 20 |
} |
| 21 |
|
| 22 |
define( 'NS_SHIELD_VERSION', '1.6.1' ); |
| 23 |
|
| 24 |
/** |
| 25 |
* Filter admin title so it's never null. |
| 26 |
* |
| 27 |
* @param string $title Admin page title. |
| 28 |
* @return string Modified title. |
| 29 |
*/ |
| 30 |
function ns_shield_fix_admin_title( $title ) { |
| 31 |
return (string) $title; |
| 32 |
} |
| 33 |
add_filter( 'admin_title', 'ns_shield_fix_admin_title', 0, 1 ); |
| 34 |
|
| 35 |
/** |
| 36 |
* Define tooltip function for login URL explanation. |
| 37 |
*/ |
| 38 |
if ( ! function_exists( 'ns_shield_get_login_url_tooltip' ) ) { |
| 39 |
function ns_shield_get_login_url_tooltip() { |
| 40 |
return __( |
| 41 |
'Changing the login URL helps protect your site from brute-force attacks aimed at the default wp-login.php endpoint. If the default URL remains unchanged, attackers could easily target it to attempt password cracking or credential stuffing attacks.', |
| 42 |
'netsensai-shield' |
| 43 |
); |
| 44 |
} |
| 45 |
} |
| 46 |
|
| 47 |
/** |
| 48 |
* Include plugin function files. |
| 49 |
*/ |
| 50 |
require_once plugin_dir_path( __FILE__ ) . 'includes/login_url_functions.php'; |
| 51 |
require_once plugin_dir_path( __FILE__ ) . 'includes/disable_wp_api_json.php'; |
| 52 |
require_once plugin_dir_path( __FILE__ ) . 'includes/disable_username_enumeration.php'; |
| 53 |
require_once plugin_dir_path( __FILE__ ) . 'includes/disable_xml_rpc.php'; |
| 54 |
require_once plugin_dir_path( __FILE__ ) . 'includes/disable_app_passwords.php'; |
| 55 |
require_once plugin_dir_path( __FILE__ ) . 'includes/disable_file_editor.php'; |
| 56 |
require_once plugin_dir_path( __FILE__ ) . 'includes/apply_security_headers.php'; |
| 57 |
require_once plugin_dir_path( __FILE__ ) . 'includes/disable_directory_indexing.php'; |
| 58 |
require_once plugin_dir_path( __FILE__ ) . 'includes/disable_default_admin.php'; |
| 59 |
require_once plugin_dir_path( __FILE__ ) . 'includes/apply_hsts_header.php'; |
| 60 |
//require_once plugin_dir_path( __FILE__ ) . 'includes/integrations/class-ns-shield-cache-integrator.php'; |
| 61 |
// Wczytaj integracje |
| 62 |
function ns_shield_load_integrations() { |
| 63 |
$ns_shield_integration_dir = plugin_dir_path( __FILE__ ) . 'includes/integrations/'; |
| 64 |
|
| 65 |
if ( is_dir( $ns_shield_integration_dir ) ) { |
| 66 |
foreach ( glob( $ns_shield_integration_dir . '*.php' ) as $ns_shield_integration_file ) { |
| 67 |
require_once $ns_shield_integration_file; |
| 68 |
} |
| 69 |
} |
| 70 |
} |
| 71 |
ns_shield_load_integrations(); |
| 72 |
|
| 73 |
// Inicjalizacja integratora cache |
| 74 |
function ns_shield_init_cache_integrator() { |
| 75 |
new NS_Shield_Cache_Integrator(); |
| 76 |
} |
| 77 |
add_action( 'plugins_loaded', 'ns_shield_init_cache_integrator' ); |
| 78 |
|
| 79 |
/** |
| 80 |
* Add settings link on the plugins page. |
| 81 |
* |
| 82 |
* @param array $links Array of action links. |
| 83 |
* @return array Modified links. |
| 84 |
*/ |
| 85 |
function ns_shield_settings_link( $links ) { |
| 86 |
$settings_link = '<a href="options-general.php?page=secure-options">' . esc_html__( 'Settings', 'netsensai-shield' ) . '</a>'; |
| 87 |
array_unshift( $links, $settings_link ); |
| 88 |
return $links; |
| 89 |
} |
| 90 |
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'ns_shield_settings_link' ); |
| 91 |
|
| 92 |
/* ===================== |
| 93 |
SETTINGS PAGE |
| 94 |
===================== */ |
| 95 |
|
| 96 |
/** |
| 97 |
* Display the settings page. |
| 98 |
*/ |
| 99 |
function ns_shield_secure_options_page() { |
| 100 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 101 |
wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'netsensai-shield' ) ); |
| 102 |
} |
| 103 |
|
| 104 |
// Ścieżka do logo |
| 105 |
$logo_url = plugin_dir_url( __FILE__ ) . 'assets/ns_logo.png'; |
| 106 |
|
| 107 |
// Tworzymy treść dla popupu z możliwości� |
| 108 |
tłumaczenia. |
| 109 |
// Używamy __() dla tekstu zawieraj� |
| 110 |
cego znaczniki <a> aby linki były działaj� |
| 111 |
ce. |
| 112 |
$enable_html = sprintf( |
| 113 |
'<div class="ns-popup-logo-container"> |
| 114 |
<img src="%1$s" alt="%2$s" class="ns-popup-logo" /> |
| 115 |
</div> |
| 116 |
<div class="ns-popup-text"> |
| 117 |
<p>%3$s</p> |
| 118 |
<p>%4$s</p> |
| 119 |
<p>%5$s</p> |
| 120 |
<p><strong>%6$s</strong> <a href="https://netsensai.pl/store" target="_blank">netsensai.pl/store</a></p> |
| 121 |
</div> |
| 122 |
<div class="ns-popup-button-container"> |
| 123 |
<button id="ns-shield-modal-ok" class="ns-modal-ok-button">%7$s</button> |
| 124 |
</div>', |
| 125 |
esc_url( $logo_url ), |
| 126 |
esc_attr__( 'Netsensai Shield Logo', 'netsensai-shield' ), |
| 127 |
// Używamy __() zamiast esc_html__() dla akapitu ze znacznikami <a> |
| 128 |
__( 'Your website now achieves top scores in the most popular security scanners. (Check <a href="https://securityheaders.com" target="_blank">securityheaders.com</a> or <a href="https://observatory.mozilla.org" target="_blank">Mozilla Observatory</a>) Great job!', 'netsensai-shield' ), |
| 129 |
esc_html__( 'But in the PRO Club, we do even more: we detect, block, and support.', 'netsensai-shield' ), |
| 130 |
esc_html__( 'If an attack occurs, you get 3 months of assistance on us!', 'netsensai-shield' ), |
| 131 |
esc_html__( 'Check out:', 'netsensai-shield' ), |
| 132 |
esc_html__( 'OK', 'netsensai-shield' ) |
| 133 |
); |
| 134 |
|
| 135 |
$disable_html = sprintf( |
| 136 |
'<h2 style="text-align:center; font-size:1.3em; margin-bottom:10px; color:#000;">%1$s</h2> |
| 137 |
<p style="font-size:1.1em; line-height:1.4; color:#000;">%2$s</p>', |
| 138 |
esc_html__( 'Oops...', 'netsensai-shield' ), |
| 139 |
esc_html__( 'The option has been disabled.', 'netsensai-shield' ) |
| 140 |
); |
| 141 |
?> |
| 142 |
<div id="netsensai-shield-plugin" class="wrap"> |
| 143 |
|
| 144 |
<!-- PRO version banner --> |
| 145 |
<div style="border: 1px solid #555; padding: 5px; margin: 5px 0; background-color: transparent; text-align: center; color: #fff;"> |
| 146 |
<p style="font-size: 1.2em; font-weight: bold; margin-bottom: 5px;"> |
| 147 |
<?php esc_html_e( 'Upgrade to NETSENSAI-SHIELD PRO for enhanced protection and advanced features.', 'netsensai-shield' ); ?> |
| 148 |
</p> |
| 149 |
<p> |
| 150 |
<?php esc_html_e( 'Get yours now at:', 'netsensai-shield' ); ?> |
| 151 |
<a href="https://netsensai.pl/store" target="_blank" rel="noopener noreferrer" style="color: #fff; text-decoration: underline;"> |
| 152 |
https://netsensai.pl/store |
| 153 |
</a> |
| 154 |
</p> |
| 155 |
</div> |
| 156 |
|
| 157 |
<h2><?php echo esc_html__( 'Security Options', 'netsensai-shield' ); ?></h2> |
| 158 |
|
| 159 |
<!-- Logos display --> |
| 160 |
<div style="display: flex; align-items: center; gap: 20px; margin-bottom: 10px;"> |
| 161 |
<a href="https://www.netsensai.pl/store/" target="_blank" style="display: flex; align-items: center; gap: 20px;"> |
| 162 |
<img src="<?php echo esc_url( plugin_dir_url( __FILE__ ) . 'assets/ns_logo.png' ); ?>" |
| 163 |
alt="<?php echo esc_attr__( 'Netsensai-Shield Logo', 'netsensai-shield' ); ?>" |
| 164 |
style="width: 200px; height: auto; margin-bottom: -20px;"> |
| 165 |
<img src="<?php echo esc_url( plugin_dir_url( __FILE__ ) . 'assets/netsensai.pl_logo.png' ); ?>" |
| 166 |
alt="<?php echo esc_attr__( 'Netsensai-Logo', 'netsensai-shield' ); ?>" |
| 167 |
style="width: 220px; height: auto; margin-bottom: -20px;"> |
| 168 |
</a> |
| 169 |
</div> |
| 170 |
|
| 171 |
<!-- Konfiguracja modala --> |
| 172 |
<script type="text/javascript"> |
| 173 |
window.nsShieldModalConfig = { |
| 174 |
modalShownFor: '', |
| 175 |
enableContentHTML: <?php echo wp_json_encode( $enable_html ); ?>, |
| 176 |
disableContentHTML: <?php echo wp_json_encode( $disable_html ); ?> |
| 177 |
}; |
| 178 |
</script> |
| 179 |
|
| 180 |
<form method="post" action="options.php"> |
| 181 |
<?php |
| 182 |
settings_fields( 'ns_shield_options_group' ); |
| 183 |
do_settings_sections( 'secure-options' ); |
| 184 |
?> |
| 185 |
<div class="ns-shield-settings-actions"> |
| 186 |
<?php |
| 187 |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Core function returns complete escaped button markup. |
| 188 |
echo get_submit_button( __( 'Save Changes', 'netsensai-shield' ), 'primary', 'submit', false ); |
| 189 |
if ( function_exists( 'ns_shield_access_details_current_guide_button' ) ) { |
| 190 |
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Helper returns fixed, internally escaped button markup. |
| 191 |
echo ns_shield_access_details_current_guide_button(); |
| 192 |
} |
| 193 |
?> |
| 194 |
</div> |
| 195 |
<?php |
| 196 |
?> |
| 197 |
</form> |
| 198 |
|
| 199 |
<!-- Include modal popup file from includes/ --> |
| 200 |
<?php |
| 201 |
$modal_file = plugin_dir_path( __FILE__ ) . 'includes/modal_popup.php'; |
| 202 |
if ( file_exists( $modal_file ) ) { |
| 203 |
include $modal_file; |
| 204 |
} |
| 205 |
// Jeśli plik nie zostanie znaleziony, nie rób nic – error_log() zostało usunięte. |
| 206 |
?> |
| 207 |
</div> <!-- End of wrap --> |
| 208 |
<?php |
| 209 |
} |
| 210 |
|
| 211 |
/** |
| 212 |
* Add settings menu in the admin. |
| 213 |
*/ |
| 214 |
function ns_shield_secure_options_menu() { |
| 215 |
add_options_page( |
| 216 |
esc_html__( 'Security Options', 'netsensai-shield' ), |
| 217 |
esc_html__( 'Security Options', 'netsensai-shield' ), |
| 218 |
'manage_options', |
| 219 |
'secure-options', |
| 220 |
'ns_shield_secure_options_page' |
| 221 |
); |
| 222 |
} |
| 223 |
add_action( 'admin_menu', 'ns_shield_secure_options_menu' ); |
| 224 |
|
| 225 |
/** |
| 226 |
* Register settings and fields. |
| 227 |
*/ |
| 228 |
function ns_shield_secure_options_settings() { |
| 229 |
register_setting( 'ns_shield_options_group', 'ns_shield_login_url', 'sanitize_text_field' ); |
| 230 |
register_setting( 'ns_shield_options_group', 'ns_shield_login_url_enabled', 'sanitize_text_field' ); |
| 231 |
register_setting( 'ns_shield_options_group', 'ns_shield_wp_api_json', 'sanitize_text_field' ); |
| 232 |
register_setting( |
| 233 |
'ns_shield_options_group', |
| 234 |
'ns_shield_username_protection', |
| 235 |
array( |
| 236 |
'type' => 'boolean', |
| 237 |
'sanitize_callback' => 'ns_shield_sanitize_username_protection', |
| 238 |
'default' => false, |
| 239 |
) |
| 240 |
); |
| 241 |
register_setting( 'ns_shield_options_group', 'ns_shield_xml_rpc', 'sanitize_text_field' ); |
| 242 |
register_setting( 'ns_shield_options_group', 'ns_shield_file_editor', 'sanitize_text_field' ); |
| 243 |
register_setting( 'ns_shield_options_group', 'ns_shield_app_passwords', 'absint' ); |
| 244 |
register_setting( 'ns_shield_options_group', 'ns_shield_security_headers', 'sanitize_text_field' ); |
| 245 |
register_setting( 'ns_shield_options_group', 'ns_shield_directory_indexing', 'sanitize_text_field' ); |
| 246 |
register_setting( 'ns_shield_options_group', 'ns_shield_default_admin', 'absint' ); |
| 247 |
register_setting( 'ns_shield_options_group', 'ns_shield_new_admin_login', 'sanitize_text_field' ); |
| 248 |
register_setting( 'ns_shield_options_group', 'ns_shield_debug', 'sanitize_text_field' ); |
| 249 |
// Register new settings for CSP headers. |
| 250 |
register_setting( 'ns_shield_options_group', 'ns_shield_csp_header_light', 'intval' ); |
| 251 |
register_setting( 'ns_shield_options_group', 'ns_shield_csp_header_hard', 'ns_shield_sanitize_csp_hard' ); |
| 252 |
|
| 253 |
// Level 1: Basic Security (login URL options etc.) |
| 254 |
add_settings_section( 'ns_shield_level_1', esc_html__( 'Level 1: Basic Security', 'netsensai-shield' ), null, 'secure-options' ); |
| 255 |
add_settings_field( 'ns_shield_login_url', esc_html__( 'Change Login URL', 'netsensai-shield' ), 'ns_shield_change_login_url', 'secure-options', 'ns_shield_level_1' ); |
| 256 |
add_settings_field( 'ns_shield_default_admin', esc_html__( 'Disable Default Admin', 'netsensai-shield' ), 'ns_shield_disable_default_admin', 'secure-options', 'ns_shield_level_1' ); |
| 257 |
add_settings_field( 'ns_shield_xml_rpc', esc_html__( 'Disable XML-RPC', 'netsensai-shield' ), 'ns_shield_field_xml_rpc', 'secure-options', 'ns_shield_level_1' ); |
| 258 |
|
| 259 |
// Level 2: Intermediate Security |
| 260 |
add_settings_section( 'ns_shield_level_2', esc_html__( 'Level 2: Intermediate Security', 'netsensai-shield' ), null, 'secure-options' ); |
| 261 |
add_settings_field( 'ns_shield_wp_api_json', esc_html__( 'Disable WP API JSON', 'netsensai-shield' ), 'ns_shield_field_wp_api_json', 'secure-options', 'ns_shield_level_2' ); |
| 262 |
add_settings_field( 'ns_shield_file_editor', esc_html__( 'Disable File Editor', 'netsensai-shield' ), 'ns_shield_field_file_editor', 'secure-options', 'ns_shield_level_2' ); |
| 263 |
add_settings_field( 'ns_shield_app_passwords', esc_html__( 'Disable WordPress Application Passwords', 'netsensai-shield' ), 'ns_shield_field_app_passwords', 'secure-options', 'ns_shield_level_2' ); |
| 264 |
|
| 265 |
// Level 3: Advanced Security |
| 266 |
add_settings_section( 'ns_shield_level_3', esc_html__( 'Level 3: Advanced Security', 'netsensai-shield' ), null, 'secure-options' ); |
| 267 |
add_settings_field( 'ns_shield_directory_indexing', esc_html__( 'Disable Directory Indexing', 'netsensai-shield' ), 'ns_shield_field_directory_indexing', 'secure-options', 'ns_shield_level_3' ); |
| 268 |
add_settings_field( 'ns_shield_username_protection', esc_html__( 'Protect Usernames', 'netsensai-shield' ), 'ns_shield_field_username_protection', 'secure-options', 'ns_shield_level_3' ); |
| 269 |
add_settings_field( 'ns_shield_security_headers', esc_html__( 'Apply Security Headers', 'netsensai-shield' ), 'ns_shield_field_security_headers', 'secure-options', 'ns_shield_level_3' ); |
| 270 |
} |
| 271 |
add_action( 'admin_init', 'ns_shield_secure_options_settings' ); |
| 272 |
|
| 273 |
/* ===================== |
| 274 |
FIELD CALLBACKS |
| 275 |
===================== */ |
| 276 |
|
| 277 |
function ns_shield_field_xml_rpc() { |
| 278 |
$checked = get_option( 'ns_shield_xml_rpc', 0 ) ? 'checked' : ''; |
| 279 |
echo '<label class="switch">'; |
| 280 |
echo '<input type="checkbox" name="ns_shield_xml_rpc" value="1" ' . esc_attr( $checked ) . '>'; |
| 281 |
echo '<span class="slider round"></span>'; |
| 282 |
echo '<div class="tooltip">' . |
| 283 |
esc_html__( |
| 284 |
'Disabling XML-RPC blocks unauthorized remote access attempts, which can enhance security. If XML-RPC remains enabled, hackers might attempt to perform DDoS attacks by sending multiple requests or brute-force password attacks to gain control over your site.', |
| 285 |
'netsensai-shield' |
| 286 |
) . |
| 287 |
'</div>'; |
| 288 |
echo '</label>'; |
| 289 |
} |
| 290 |
|
| 291 |
function ns_shield_field_wp_api_json() { |
| 292 |
$checked = get_option( 'ns_shield_wp_api_json', 0 ) ? 'checked' : ''; |
| 293 |
echo '<label class="switch">'; |
| 294 |
echo '<input type="checkbox" name="ns_shield_wp_api_json" value="1" ' . esc_attr( $checked ) . '>'; |
| 295 |
echo '<span class="slider round"></span>'; |
| 296 |
echo '<div class="tooltip">' . |
| 297 |
esc_html__( |
| 298 |
'Disabling WP API JSON can protect your site from unauthorized access to sensitive data through the API. If left enabled, hackers may exploit WP API JSON to gather information about your site’s structure or perform enumeration attacks on users, which can lead to brute-force attacks.', |
| 299 |
'netsensai-shield' |
| 300 |
) . |
| 301 |
'</div>'; |
| 302 |
echo '</label>'; |
| 303 |
} |
| 304 |
|
| 305 |
function ns_shield_field_file_editor() { |
| 306 |
$checked = get_option( 'ns_shield_file_editor', 0 ) ? 'checked' : ''; |
| 307 |
echo '<label class="switch">'; |
| 308 |
echo '<input type="checkbox" name="ns_shield_file_editor" value="1" ' . esc_attr( $checked ) . '>'; |
| 309 |
echo '<span class="slider round"></span>'; |
| 310 |
echo '<div class="tooltip">' . |
| 311 |
esc_html__( |
| 312 |
'Disabling the file editor in the WP dashboard prevents unauthorized or accidental code changes. If left enabled, attackers who gain access to your admin panel could inject malicious code into your theme or plugin files, leading to a defacement of the site or the deployment of malware.', |
| 313 |
'netsensai-shield' |
| 314 |
) . |
| 315 |
'</div>'; |
| 316 |
echo '</label>'; |
| 317 |
} |
| 318 |
|
| 319 |
function ns_shield_field_app_passwords() { |
| 320 |
$checked = get_option( 'ns_shield_app_passwords', 0 ) ? 'checked' : ''; |
| 321 |
echo '<label class="switch">'; |
| 322 |
echo '<input type="checkbox" name="ns_shield_app_passwords" value="1" ' . esc_attr( $checked ) . '>'; |
| 323 |
echo '<span class="slider round"></span>'; |
| 324 |
echo '<div class="tooltip">' . |
| 325 |
esc_html__( |
| 326 |
'Disabling application passwords secures against creating unauthorized accesses to your site’s API. If left enabled, hackers may exploit application passwords to gain persistent access to your site, enabling them to execute unauthorized API requests or even escalate their privileges.', |
| 327 |
'netsensai-shield' |
| 328 |
) . |
| 329 |
'</div>'; |
| 330 |
echo '</label>'; |
| 331 |
} |
| 332 |
|
| 333 |
function ns_shield_field_security_headers() { |
| 334 |
$checked = get_option( 'ns_shield_security_headers', 0 ) ? 'checked' : ''; |
| 335 |
echo '<label class="switch">'; |
| 336 |
echo '<input type="checkbox" name="ns_shield_security_headers" id="ns-shield-preload-checkbox" value="1" ' . esc_attr( $checked ) . '>'; |
| 337 |
echo '<span class="slider round"></span>'; |
| 338 |
echo '<div class="tooltip">' . |
| 339 |
esc_html__( |
| 340 |
'Applying security headers can protect your site from XSS attacks and other threats. On HTTPS pages, this also enables basic HSTS for the current domain only. Without these headers, your site could be vulnerable to cross-site scripting (XSS) attacks or clickjacking, allowing attackers to steal sensitive data or trick users into executing malicious actions.', |
| 341 |
'netsensai-shield' |
| 342 |
) . |
| 343 |
'</div>'; |
| 344 |
echo '</label>'; |
| 345 |
} |
| 346 |
|
| 347 |
/** |
| 348 |
* FIELD CALLBACK: Directory Indexing. |
| 349 |
*/ |
| 350 |
function ns_shield_field_directory_indexing() { |
| 351 |
$checked = get_option( 'ns_shield_directory_indexing', 0 ) ? 'checked' : ''; |
| 352 |
echo '<label class="switch">'; |
| 353 |
echo '<input type="checkbox" name="ns_shield_directory_indexing" value="1" ' . esc_attr( $checked ) . '>'; |
| 354 |
echo '<span class="slider round"></span>'; |
| 355 |
echo '<div class="tooltip">' . |
| 356 |
esc_html__( |
| 357 |
'Directory indexing allows attackers to list and access files in directories that lack an index file, exposing sensitive files and configurations. If directory indexing is not disabled, attackers can execute Directory Traversal attacks, gaining access to configuration files, logs, or even databases.', |
| 358 |
'netsensai-shield' |
| 359 |
) . |
| 360 |
'</div>'; |
| 361 |
echo '</label>'; |
| 362 |
} |
| 363 |
|
| 364 |
/** |
| 365 |
* FIELD CALLBACK: Username protection. |
| 366 |
* |
| 367 |
* @return void |
| 368 |
*/ |
| 369 |
function ns_shield_field_username_protection() { |
| 370 |
$checked = ns_shield_username_protection_is_enabled() ? 'checked' : ''; |
| 371 |
|
| 372 |
echo '<label class="switch">'; |
| 373 |
echo '<input type="checkbox" name="ns_shield_username_protection" value="1" ' . esc_attr( $checked ) . '>'; |
| 374 |
echo '<span class="slider round"></span>'; |
| 375 |
echo '<div class="tooltip">' . esc_html__( 'Makes it harder for unauthenticated visitors to discover account usernames and IDs through author archives and the REST API. It does not hide author names intentionally published on the website.', 'netsensai-shield' ) . '</div>'; |
| 376 |
echo '</label>'; |
| 377 |
} |
| 378 |
|
| 379 |
/** |
| 380 |
* Flush rewrite rules on plugin activation. |
| 381 |
*/ |
| 382 |
function ns_shield_activation_flush() { |
| 383 |
ns_shield_migrate_legacy_hsts(); |
| 384 |
|
| 385 |
if ( function_exists( 'ns_shield_add_rewrite_rule' ) ) { |
| 386 |
ns_shield_add_rewrite_rule(); |
| 387 |
} |
| 388 |
flush_rewrite_rules(); |
| 389 |
} |
| 390 |
register_activation_hook( __FILE__, 'ns_shield_activation_flush' ); |
| 391 |
|
| 392 |
/** |
| 393 |
* Flush rewrite rules on plugin deactivation. |
| 394 |
*/ |
| 395 |
function ns_shield_deactivation_flush() { |
| 396 |
flush_rewrite_rules(); |
| 397 |
} |
| 398 |
register_deactivation_hook( __FILE__, 'ns_shield_deactivation_flush' ); |
| 399 |
|
| 400 |
|
| 401 |
// Wskazanie uruchomienia pliku script.js |
| 402 |
function ns_shield_admin_enqueue_assets( $hook_suffix ) { |
| 403 |
// tylko na /wp-admin/options-general.php?page=secure-options |
| 404 |
if ( 'settings_page_secure-options' !== $hook_suffix ) { |
| 405 |
return; |
| 406 |
} |
| 407 |
|
| 408 |
// a) Styl |
| 409 |
wp_enqueue_style( |
| 410 |
'ns_shield-style', |
| 411 |
plugin_dir_url( __FILE__ ) . 'assets/style.css', |
| 412 |
[], |
| 413 |
filemtime( plugin_dir_path( __FILE__ ) . 'assets/style.css' ) |
| 414 |
); |
| 415 |
|
| 416 |
// b) Skrypt z filemtime jako wersj� |
| 417 |
|
| 418 |
$script_path = plugin_dir_path( __FILE__ ) . 'assets/script.js'; |
| 419 |
$ver = file_exists( $script_path ) ? filemtime( $script_path ) : false; |
| 420 |
wp_enqueue_script( |
| 421 |
'ns_shield-script', |
| 422 |
plugin_dir_url( __FILE__ ) . 'assets/script.js', |
| 423 |
['jquery'], |
| 424 |
$ver, |
| 425 |
true |
| 426 |
); |
| 427 |
|
| 428 |
// c) Przekazanie ustawień do JS |
| 429 |
wp_localize_script( 'ns_shield-script', 'nsShieldSettings', [ |
| 430 |
'pageSlug' => 'secure-options', |
| 431 |
] ); |
| 432 |
} |
| 433 |
add_action( 'admin_enqueue_scripts', 'ns_shield_admin_enqueue_assets' ); |
| 434 |
|
| 435 |
|
| 436 |
?> |
| 437 |
|