PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.9.1
WP 2FA – Two-factor authentication for WordPress v2.9.1
1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / includes / classes / Admin / class-user-notices.php
wp-2fa / includes / classes / Admin Last commit date
Controllers 11 months ago Fly-Out 11 months ago Helpers 11 months ago Methods 11 months ago SettingsPages 11 months ago Views 11 months ago class-help-contact-us.php 11 months ago class-plugin-updated-notice.php 11 months ago class-premium-features.php 11 months ago class-settings-page.php 11 months ago class-setup-wizard.php 11 months ago class-user-listing.php 11 months ago class-user-notices.php 11 months ago class-user-profile.php 11 months ago class-user-registered.php 11 months ago index.php 11 months ago
class-user-notices.php
269 lines
1 <?php
2 /**
3 * Responsible for WP2FA user's notifying.
4 *
5 * @package wp2fa
6 * @subpackage user-utils
7 * @copyright 2025 Melapress
8 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
9 * @link https://wordpress.org/plugins/wp-2fa/
10 */
11
12 namespace WP2FA\Admin;
13
14 use WP2FA\WP2FA;
15 use WP2FA\Extensions_Loader;
16 use WP2FA\Utils\Settings_Utils;
17 use WP2FA\Admin\Helpers\WP_Helper;
18 use WP2FA\Freemius\User_Licensing;
19 use WP2FA\Admin\Controllers\Methods;
20 use WP2FA\Admin\Helpers\User_Helper;
21 use WP2FA\Admin\Controllers\Settings;
22 use WP2FA\Admin\Views\Grace_Period_Notifications;
23 use WP2FA\Admin\SettingsPages\Settings_Page_White_Label;
24
25 /**
26 * User_Notices class with user notification filters
27 *
28 * @since 2.4.0
29 */
30 if ( ! class_exists( '\WP2FA\Admin\User_Notices' ) ) {
31 /**
32 * User_Notices - Class for displaying notices to our users.
33 */
34 class User_Notices {
35
36 /**
37 * Lets set things up
38 */
39 public static function init() {
40 $user = User_Helper::get_user_object();
41 $enforcement_policy = Settings_Utils::get_setting_role( User_Helper::get_user_role( $user ), 'enforcement-policy' );
42 if ( ! empty( $enforcement_policy ) ) {
43 // Check we are supposed to, before adding action to show nag.
44 if ( in_array( $enforcement_policy, array( 'all-users', 'certain-roles-only', 'certain-users-only', 'superadmins-only', 'superadmins-siteadmins-only', 'enforce-on-multisite', true ), true ) ) {
45
46 $global_methods = Methods::get_available_2fa_methods( User_Helper::get_user_role() );
47 $users_method = User_Helper::get_enabled_method_for_user( User_Helper::get_user_object() );
48
49 if ( Grace_Period_Notifications::notify_using_dashboard( User_Helper::get_user_object() ) ) {
50 add_action( 'admin_notices', array( __CLASS__, 'user_setup_2fa_nag' ) );
51 add_action( 'network_admin_notices', array( __CLASS__, 'user_setup_2fa_nag' ) );
52 }
53
54 // If enabled method is no longer available, show nag so users reconfigures using an available remaining method.
55 if ( User_Helper::is_enforced( $user ) && ! empty( $users_method ) && empty( \array_intersect( array( $users_method ), $global_methods ) ) ) {
56 }
57 } elseif ( 'do-not-enforce' === Settings_Utils::get_setting_role( User_Helper::get_user_role( $user ), 'enforcement-policy' ) ) {
58 add_action( 'admin_notices', array( __CLASS__, 'user_reconfigure_2fa_nag' ) );
59 add_action( 'network_admin_notices', array( __CLASS__, 'user_setup_2fa_nag' ) );
60 }
61 }
62 }
63
64 /**
65 * The nag content
66 *
67 * @param string $is_shortcode - Is that a call from shortcode.
68 * @param string $configure_2fa_url - The configuration url.
69 *
70 * @return void
71 */
72 public static function user_setup_2fa_nag( $is_shortcode = '', $configure_2fa_url = '' ) {
73
74 if ( isset( $_GET['user_id'] ) ) { // phpcs:ignore
75 $current_profile_user_id = (int) $_GET['user_id']; // phpcs:ignore
76 } elseif ( ! is_null( User_Helper::get_user_object() ) ) {
77 $current_profile_user_id = User_Helper::get_user_object()->ID;
78 } else {
79 $current_profile_user_id = false;
80 }
81
82 if ( ! $current_profile_user_id ||
83 isset( $_GET['user_id'] ) && // phpcs:ignore
84 $_GET['user_id'] !== User_Helper::get_user_object()->ID || // phpcs:ignore
85 User_Helper::get_user_enforced_instantly( User_Helper::get_user_object() ) ) {
86 return;
87 }
88
89 $grace_expiry = (int) User_Helper::get_user_expiry_date( User_Helper::get_user_object() );
90
91 $class = 'notice notice-info wp-2fa-nag';
92
93 if ( User_Helper::get_user_needs_to_reconfigure_2fa( User_Helper::get_user_object() ) ) {
94 $message = WP2FA::get_wp2fa_white_label_setting( 'default-2fa-resetup-required-notice', true );
95 } else {
96 $message = WP2FA::get_wp2fa_white_label_setting( 'default-2fa-required-notice', true );
97 }
98
99 $is_nag_dismissed = User_Helper::get_nag_status();
100 $is_nag_needed = User_Helper::is_enforced( User_Helper::get_user_object()->ID );
101 $is_user_excluded = User_Helper::is_excluded( User_Helper::get_user_object()->ID );
102 $enabled_methods = User_Helper::get_enabled_method_for_user( User_Helper::get_user_object() );
103 $new_page_id = Settings_Utils::get_setting_role( User_Helper::get_user_role(), 'custom-user-page-id' );
104
105 if ( empty( $new_page_id ) ) {
106 $new_page_id = Settings::get_custom_settings_page_id( '', User_Helper::get_user_object() );
107 }
108
109 $new_page_permalink = get_permalink( $new_page_id );
110
111 $setup_url = Settings::get_setup_page_link();
112
113 // Allow setup URL to be customized if outputting via shortcode.
114 if ( isset( $is_shortcode ) && 'output_shortcode' === $is_shortcode && ! empty( $configure_2fa_url ) ) {
115 $setup_url = $configure_2fa_url;
116 }
117
118 // Stop the page from being a link to a page this user cant access if needed.
119 if ( WP_Helper::is_multisite() && ! is_user_member_of_blog( User_Helper::get_user_object()->ID ) ) {
120 $new_page_id = false;
121 }
122
123 // If we have a custom page generated, lets use it.
124 if ( ! empty( $new_page_id ) && $new_page_permalink ) {
125 $setup_url = $new_page_permalink;
126 }
127
128 // If the nag has not already been dismissed, and of course if the user is eligible, lets show them something.
129 if ( ! $is_nag_dismissed && $is_nag_needed && empty( $enabled_methods ) && ! $is_user_excluded && ! empty( $grace_expiry ) ) {
130
131 $show = true;
132
133 if ( class_exists( '\WP2FA\Freemius\User_Licensing' ) ) {
134 if ( Extensions_Loader::use_proxytron() ) {
135 $show = User_Licensing::enable_2fa_user_setting( true );
136 }
137 }
138
139 if ( $show ) {
140 echo '<div class="' . \esc_attr( $class ) . '">';
141 echo wpautop( \wp_kses_post( WP2FA::replace_remaining_grace_period( $message, (int) $grace_expiry ) ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
142 echo ' <a href="' . \esc_url( $setup_url ) . '" class="button button-primary">' . \esc_html__( 'Configure 2FA now', 'wp-2fa' ) . '</a>';
143 echo ' <a href="#" class="button button-secondary dismiss-user-configure-nag">' . \esc_html__( 'Remind me on next login', 'wp-2fa' ) . '</a></p>';
144 echo '</div>';
145 }
146 } else {
147 self::user_reconfigure_2fa_nag();
148 }
149 }
150
151 /**
152 * The nag content
153 *
154 * @since 3.0.0
155 */
156 public static function user_reconfigure_2fa_nag() {
157
158 // If the nag has not already been dismissed, and of course if the user is eligible, lets show them something.
159 if ( User_Helper::needs_to_reconfigure_method() ) {
160 $class = 'notice notice-info wp-2fa-nag';
161
162 $message = \esc_html__( 'The 2FA method you were using is no longer allowed on this website. Please reconfigure 2FA using one of the supported methods.', 'wp-2fa' );
163
164 echo '<div class="' . \esc_attr( $class ) . '"><p>' . \esc_html( $message );
165 echo ' <a href="' . \esc_url( Settings::get_setup_page_link() ) . '" class="button button-primary">' . \esc_html__( 'Configure 2FA now', 'wp-2fa' ) . '</a>';
166 echo ' <a href="#" class="button button-secondary wp-2fa-button-secondary dismiss-user-reconfigure-nag">' . \esc_html__( 'I\'ll do it later', 'wp-2fa' ) . '</a></p>';
167 echo '</div>';
168 }
169 }
170
171
172 /**
173 * Dismiss notice and setup a user meta value so we know its been dismissed
174 *
175 * @since 3.0.0
176 */
177 public static function dismiss_nag() {
178 User_Helper::set_nag_status( true );
179 }
180
181 /**
182 * Reset the nag when the user logs out, so they get it again next time.
183 *
184 * @param int $user_id - The ID of the user.
185 *
186 * @return void
187 *
188 * @since 3.0.0
189 */
190 public static function reset_nag( $user_id ) {
191 User_Helper::remove_nag_status( $user_id );
192 }
193
194 /**
195 * Adds setting option in the white label settings page.
196 *
197 * @return void
198 *
199 * @since 2.5.0
200 */
201 public static function white_label_settings_text() {
202 ?>
203 <tr>
204 <th><label for="email-backup-method"><?php \esc_html_e( '2FA mandatory notice', 'wp-2fa' ); ?></label></th>
205 <td>
206 <?php
207 echo Settings_Page_White_Label::create_standard_editor( 'default-2fa-required-notice' ); // phpcs:ignore
208 ?>
209 <div style="margin-top: 5px;"><span><strong><i><?php \esc_html_e( 'Note:', 'wp-2fa' ); ?></i></strong> <?php \esc_html_e( 'Only plain text is allowed.', 'wp-2fa' ); ?></span></div>
210 </td>
211 </tr>
212 <tr>
213 <th><label for="email-backup-method"><?php \esc_html_e( '2FA reconfiguration mandatory notice', 'wp-2fa' ); ?></label></th>
214 <td>
215 <?php
216 echo Settings_Page_White_Label::create_standard_editor( 'default-2fa-resetup-required-notice' ); // phpcs:ignore
217 ?>
218 <div style="margin-top: 5px;"><span><strong><i><?php \esc_html_e( 'Note:', 'wp-2fa' ); ?></i></strong> <?php \esc_html_e( 'Only plain text is allowed.', 'wp-2fa' ); ?></span></div>
219 </td>
220 </tr>
221 <tr>
222 <th><label><?php \esc_html_e( 'User profile 2FA configuration area title', 'wp-2fa' ); ?></label></th>
223 <td>
224 <?php
225 echo Settings_Page_White_Label::create_standard_editor( 'user-profile-form-preamble-title' ); // phpcs:ignore
226 ?>
227 <div style="margin-top: 5px;"><span><strong><i><?php \esc_html_e( 'Note:', 'wp-2fa' ); ?></i></strong> <?php \esc_html_e( 'Only plain text is allowed.', 'wp-2fa' ); ?></span></div>
228 </td>
229 </tr>
230 <tr>
231 <th><label><?php \esc_html_e( 'User profile 2FA configuration area description', 'wp-2fa' ); ?></label></th>
232 <td>
233 <?php
234 echo Settings_Page_White_Label::create_standard_editor( 'user-profile-form-preamble-desc' ); // phpcs:ignore
235 ?>
236 <div style="margin-top: 5px;"><span><strong><i><?php \esc_html_e( 'Note:', 'wp-2fa' ); ?></i></strong> <?php \esc_html_e( 'Only plain text is allowed.', 'wp-2fa' ); ?></span></div>
237 </td>
238 </tr>
239 <?php
240 // phpcs:disable
241 // phpcs:enable
242 ?>
243 <?php
244 }
245
246 /**
247 * Adds and filters extension values in the settings store array ($output).
248 *
249 * @param array $output - Array with the currently stored settings.
250 * @param array $input - Array with the input ($_POST) values.
251 *
252 * @return array
253 *
254 * @since 2.5.0
255 */
256 public static function settings_store( array $output, array $input ) {
257 if ( isset( $input['default-2fa-required-notice'] ) ) {
258 $output['default-2fa-required-notice'] = \wp_kses_post( $input['default-2fa-required-notice'] );
259 }
260
261 if ( isset( $input['default-2fa-resetup-required-notice'] ) ) {
262 $output['default-2fa-resetup-required-notice'] = \wp_kses_post( $input['default-2fa-resetup-required-notice'] );
263 }
264
265 return $output;
266 }
267 }
268 }
269