PluginProbe ʕ •ᴥ•ʔ
Limit Login Attempts Security – Login Security, 2FA, Firewall, Brute Force Prevention / 3.2.4
Limit Login Attempts Security – Login Security, 2FA, Firewall, Brute Force Prevention v3.2.4
3.2.4 3.2.3 3.2.2 3.2.1 3.2.0 trunk 2.0.0 2.1.0 2.10.0 2.10.1 2.11.0 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.14.0 2.15.0 2.15.1 2.15.2 2.16.0 2.17.0 2.17.1 2.17.2 2.17.3 2.17.4 2.18.0 2.19.0 2.19.1 2.19.2 2.2.0 2.20.0 2.20.1 2.20.2 2.20.3 2.20.4 2.20.5 2.20.6 2.21.0 2.21.1 2.22.0 2.22.1 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.25.0 2.25.1 2.25.10 2.25.11 2.25.12 2.25.13 2.25.14 2.25.15 2.25.16 2.25.17 2.25.18 2.25.19 2.25.2 2.25.20 2.25.21 2.25.22 2.25.23 2.25.24 2.25.25 2.25.26 2.25.27 2.25.28 2.25.29 2.25.3 2.25.4 2.25.5 2.25.6 2.25.7 2.25.8 2.25.9 2.26.0 2.26.1 2.26.10 2.26.11 2.26.12 2.26.13 2.26.14 2.26.15 2.26.16 2.26.17 2.26.18 2.26.19 2.26.2 2.26.20 2.26.21 2.26.22 2.26.23 2.26.24 2.26.25 2.26.26 2.26.27 2.26.28 2.26.3 2.26.4 2.26.5 2.26.6 2.26.7 2.26.8 2.26.9 2.3.0 2.4.0 2.5.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.8.0 2.8.1 2.9.0 3.0.0 3.0.1 3.0.2 3.1.0
limit-login-attempts-reloaded / core / AdminNoticesController.php
limit-login-attempts-reloaded / core Last commit date
http 2 weeks ago integrations 2 weeks ago mfa 2 weeks ago mfa-flow 2 weeks ago AdminNoticesController.php 2 weeks ago Ajax.php 2 weeks ago CloudApp.php 2 weeks ago Config.php 2 weeks ago Helpers.php 2 weeks ago LimitLoginAttempts.php 2 weeks ago LoginFlowTransientStore.php 2 weeks ago MfaConstants.php 2 weeks ago Shortcodes.php 2 weeks ago
AdminNoticesController.php
169 lines
1 <?php
2
3 namespace LLAR\Core;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit;
7 }
8
9 /**
10 * Renders admin notices for the LLAR options page.
11 * All notices use a single view; content is built from config per notice key.
12 */
13 class AdminNoticesController {
14
15 /**
16 * Allowed notice keys.
17 *
18 * @var array
19 */
20 private static $allowed = array( 'auto-update', 'https-recommended', 'https-recommended-mfa', 'debug-foreign-auth-hooks', 'flash', 'mfa-recovery-links-expired' );
21
22 /**
23 * Get type, CSS class and HTML content for a notice key.
24 *
25 * @param string $notice_key Notice identifier.
26 * @param array $args Optional. For 'flash' key: 'msg', 'is_error'.
27 * @return array|null Array with 'type', 'class', 'content' or null if unknown.
28 */
29 private function get_notice_config( $notice_key, array $args = array() ) {
30 $text_domain = 'limit-login-attempts-reloaded';
31 switch ( $notice_key ) {
32 case 'auto-update':
33 $content = \__( 'Do you want Limit Login Attempts Reloaded to provide the latest version automatically?', $text_domain );
34 $content .= ' <a href="#" class="auto-enable-update-option" data-val="yes">';
35 $content .= \__( 'Yes, enable auto-update', $text_domain ) . '</a> | ';
36 $content .= '<a href="#" class="auto-enable-update-option" data-val="no">';
37 $content .= \__( 'No thanks', $text_domain ) . '</a>';
38 return array(
39 'type' => 'notice-error',
40 'class' => 'llar-options-notice llar-auto-update-notice',
41 'content' => $content,
42 );
43 case 'https-recommended':
44 return array(
45 'type' => 'notice-warning',
46 'class' => 'llar-options-notice',
47 'content' => \__( 'Your site is not using HTTPS. Enabling HTTPS is recommended for better security.', $text_domain ),
48 );
49 case 'https-recommended-mfa':
50 return array(
51 'type' => 'notice-warning',
52 'class' => 'llar-options-notice',
53 'content' => \__( 'Before enabling 2FA/MFA, we strongly recommend ensuring your website is accessible only via HTTPS.', $text_domain ),
54 );
55 case 'debug-foreign-auth-hooks':
56 $hooks = isset( $args['hooks'] ) && is_array( $args['hooks'] ) ? $args['hooks'] : array();
57 if ( empty( $hooks ) ) {
58 return null;
59 }
60
61 $content = \__( 'These plugins register additional callbacks on the authenticate filter and may affect LLAR login protection.', $text_domain );
62 $grouped_hooks = array();
63 foreach ( $hooks as $hook ) {
64 $plugin_slug = 'unknown';
65 $plugin_label = 'Unknown plugin';
66 $plugin_details_url = '';
67
68 if ( ! empty( $hook['plugin'] ) && is_array( $hook['plugin'] ) ) {
69 $plugin_name = isset( $hook['plugin']['name'] ) ? (string) $hook['plugin']['name'] : '';
70 $plugin_slug_raw = isset( $hook['plugin']['slug'] ) ? (string) $hook['plugin']['slug'] : '';
71 $plugin_slug = '' !== $plugin_slug_raw ? \sanitize_key( $plugin_slug_raw ) : 'unknown';
72 $plugin_version = isset( $hook['plugin']['version'] ) ? (string) $hook['plugin']['version'] : '';
73
74 if ( '' !== $plugin_name ) {
75 $plugin_label = $plugin_name;
76 if ( '' !== $plugin_version ) {
77 $plugin_label .= ' v' . $plugin_version;
78 }
79 } elseif ( 'unknown' !== $plugin_slug ) {
80 $plugin_label = $plugin_slug;
81 }
82
83 if ( 'unknown' !== $plugin_slug ) {
84 $plugin_details_url = \admin_url(
85 'plugin-install.php?tab=plugin-information&plugin=' . rawurlencode( $plugin_slug ) . '&TB_iframe=true&width=600&height=550'
86 );
87 }
88 }
89
90 if ( ! isset( $grouped_hooks[ $plugin_slug ] ) ) {
91 $grouped_hooks[ $plugin_slug ] = array(
92 'label' => $plugin_label,
93 'url' => $plugin_details_url,
94 );
95 }
96 }
97
98 $content .= '<br /><ul style="margin-left: 18px; list-style: disc;">';
99 foreach ( $grouped_hooks as $plugin_group ) {
100 $content .= '<li><strong>' . \esc_html( $plugin_group['label'] ) . '</strong>';
101 if ( '' !== $plugin_group['url'] ) {
102 $content .= ' - <a href="' . \esc_url( $plugin_group['url'] ) . '" class="thickbox open-plugin-details-modal" target="_blank" rel="noopener noreferrer">'
103 . \esc_html__( 'View details', $text_domain ) . '</a>';
104 }
105 $content .= '</li>';
106 }
107 $content .= '</ul>';
108
109 return array(
110 'type' => 'notice-warning',
111 'class' => 'llar-options-notice',
112 'content' => $content,
113 );
114 case 'flash':
115 $msg = isset( $args['msg'] ) ? $args['msg'] : '';
116 $is_error = ! empty( $args['is_error'] );
117 if ( $msg === '' ) {
118 return null;
119 }
120 return array(
121 'type' => $is_error ? 'notice-error' : 'notice-success',
122 'class' => 'llar-options-notice llar-flash-notice',
123 'content' => $msg,
124 );
125 case 'mfa-recovery-links-expired':
126 $mfa_url = isset( $args['mfa_url'] ) ? (string) $args['mfa_url'] : '';
127 if ( '' === $mfa_url ) {
128 return null;
129 }
130 return array(
131 'type' => 'notice-error',
132 'class' => 'llar-options-notice llar-mfa-recovery-links-expired',
133 'content' => sprintf(
134 __( '⚠️ Action required: Your existing 2FA recovery links are no longer valid. On the <a href="%s">2FA settings page</a>, turn 2FA off and then back on, then follow the prompts to download the new recovery links.', 'limit-login-attempts-reloaded' ),
135 \esc_url( $mfa_url )
136 ),
137 );
138 default:
139 return null;
140 }
141 }
142
143 /**
144 * Render a notice by key.
145 *
146 * @param string $notice_key Notice identifier (e.g. 'auto-update', 'https-recommended').
147 * @param array $args Optional. Unused; reserved for future use.
148 * @return void
149 */
150 public function render( $notice_key, array $args = array() ) {
151 $notice_key = \sanitize_key( $notice_key );
152 if ( ! in_array( $notice_key, self::$allowed, true ) ) {
153 return;
154 }
155 $config = $this->get_notice_config( $notice_key, $args );
156 if ( null === $config ) {
157 return;
158 }
159 $path = LLA_PLUGIN_DIR . 'views/notices.php';
160 if ( ! is_readable( $path ) ) {
161 return;
162 }
163 $notice_type = $config['type'];
164 $notice_class = $config['class'];
165 $notice_content = $config['content'];
166 include $path;
167 }
168 }
169