PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.0.0
WP 2FA – Two-factor authentication for WordPress v2.0.0
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 / functions / core.php
wp-2fa / includes / functions Last commit date
core.php 4 years ago index.php 5 years ago login-header.php 6 years ago
core.php
333 lines
1 <?php // phpcs:ignore
2
3 /**
4 * Core plugin functionality.
5 *
6 * @package WP2FA
7 */
8
9 namespace WP2FA\Core;
10
11 use \WP2FA\Admin\SettingsPage as SettingsPage;
12 use \WP2FA\Utils\UserUtils;
13 use WP2FA\Utils\SettingsUtils as SettingsUtils;
14
15 /**
16 * Default setup routine
17 *
18 * @return void
19 */
20 function setup() {
21 $n = function( $function ) {
22 return __NAMESPACE__ . "\\$function";
23 };
24
25 add_action( 'init', $n( 'i18n' ) );
26 add_action( 'init', $n( 'init' ) );
27 add_action( 'admin_enqueue_scripts', $n( 'admin_scripts' ) );
28 add_action( 'admin_enqueue_scripts', $n( 'admin_styles' ) );
29
30 // Hook to allow async or defer on asset loading.
31 add_filter( 'script_loader_tag', $n( 'script_loader_tag' ), 10, 2 );
32
33 do_action( 'wp_2fa_loaded' );
34 }
35
36 /**
37 * Registers the default textdomain.
38 *
39 * @return void
40 */
41 function i18n() {
42 $locale = apply_filters( 'plugin_locale', get_locale(), 'wp-2fa' );
43 load_textdomain( 'wp-2fa', WP_LANG_DIR . '/wp-2fa/wp-2fa-' . $locale . '.mo' );
44 load_plugin_textdomain( 'wp-2fa', false, plugin_basename( WP_2FA_PATH ) . '/languages/' );
45 }
46
47 /**
48 * Initializes the plugin and fires an action other plugins can hook into.
49 *
50 * @return void
51 */
52 function init() {
53 do_action( 'wp_2fa_init' );
54 }
55
56 /**
57 * Activate the plugin
58 *
59 * @return void
60 */
61 function activate() {
62 // First load the init scripts in case any rewrite functionality is being loaded.
63 init();
64 flush_rewrite_rules();
65
66 // Check if the user is allowed to manage options for the site.
67 if ( current_user_can( 'manage_options' ) ) {
68 // Add an option to let our plugin know this user has not been through the setup wizard.
69 SettingsUtils::update_option( 'redirect_on_activate', true );
70 }
71
72 // Add plugin version to wp_options.
73 SettingsUtils::update_option( 'plugin_version', WP_2FA_VERSION );
74 }
75
76 /**
77 * Deactivate the plugin
78 *
79 * Uninstall routines should be in uninstall.php
80 *
81 * @return void
82 */
83 function deactivate() {
84
85 }
86
87 /**
88 * Uninstall the plugin
89 *
90 * @return void
91 */
92 function uninstall() {
93 if ( ! empty( \WP2FA\WP2FA::get_wp2fa_general_setting( 'delete_data_upon_uninstall' ) ) ) {
94 // Delete settings from wp_options.
95 if ( \WP2FA\WP2FA::is_this_multisite() ) {
96 $network_id = get_current_network_id();
97 global $wpdb;
98 $wpdb->query(
99 $wpdb->prepare(
100 "
101 DELETE FROM $wpdb->sitemeta
102 WHERE meta_key LIKE %s
103 AND site_id = %d
104 ",
105 [
106 'wp_2fa_%',
107 $network_id
108 ]
109 )
110 );
111 } else {
112 global $wpdb;
113 $wpdb->query(
114 $wpdb->prepare(
115 "
116 DELETE FROM $wpdb->options
117 WHERE option_name LIKE %s
118 ",
119 [
120 'wp_2fa_%',
121 ]
122 )
123 );
124 }
125
126 $users_args = array(
127 'fields' => array( 'ID' ),
128 );
129 if ( \WP2FA\WP2FA::is_this_multisite() ) {
130 $users_args['blog_id'] = 0;
131 }
132 $settings = new SettingsPage();
133 $users = UserUtils::get_all_user_ids( 'query', $users_args );
134 if ( ! is_array( $users ) ) {
135 $users = explode( ',', $users );
136 }
137
138 foreach ( $users as $user_id ) {
139 global $wpdb;
140 $wpdb->query(
141 $wpdb->prepare(
142 "
143 DELETE FROM $wpdb->usermeta
144 WHERE user_id = %d
145 AND meta_key LIKE %s
146 ",
147 [
148 $user_id,
149 'wp_2fa_%'
150 ]
151 )
152 );
153 }
154 }
155 }
156
157 /**
158 * The list of knows contexts for enqueuing scripts/styles.
159 *
160 * @return array
161 */
162 function get_enqueue_contexts() {
163 return array( 'admin', 'frontend', 'shared' );
164 }
165
166 /**
167 * Generate an URL to a script, taking into account whether SCRIPT_DEBUG is enabled.
168 *
169 * @param string $script Script file name (no .js extension).
170 * @param string $context Context for the script ('admin', 'frontend', or 'shared').
171 *
172 * @return string|WP_Error URL
173 */
174 function script_url( $script, $context ) {
175
176 if ( ! in_array( $context, get_enqueue_contexts(), true ) ) {
177 return new \WP_Error( 'invalid_enqueue_context', 'Invalid $context specified in WP2FA script loader.' );
178 }
179
180 return WP_2FA_URL . "dist/js/${script}.js";
181
182 }
183
184 /**
185 * Generate an URL to a stylesheet, taking into account whether SCRIPT_DEBUG is enabled.
186 *
187 * @param string $stylesheet Stylesheet file name (no .css extension).
188 * @param string $context Context for the script ('admin', 'frontend', or 'shared').
189 *
190 * @return string URL
191 */
192 function style_url( $stylesheet, $context ) {
193
194 if ( ! in_array( $context, get_enqueue_contexts(), true ) ) {
195 return new \WP_Error( 'invalid_enqueue_context', 'Invalid $context specified in WP2FA stylesheet loader.' );
196 }
197
198 return WP_2FA_URL . "dist/css/${stylesheet}.css";
199
200 }
201
202 /**
203 * Enqueue scripts for admin.
204 *
205 * @return void
206 */
207 function admin_scripts() {
208
209 global $pagenow;
210
211 // Get page argument from $_GET array.
212 $page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING );
213 if ( ( empty( $page ) || false === strpos( $page, 'wp-2fa' ) ) && "profile.php" !== $pagenow ) {
214 return;
215 }
216
217 wp_enqueue_script(
218 'wp_2fa_admin',
219 script_url( 'admin', 'admin' ),
220 array( 'jquery-ui-widget', 'jquery-ui-core', 'jquery-ui-autocomplete', 'wp_2fa_micro_modals', 'select2' ),
221 WP_2FA_VERSION,
222 true
223 );
224
225 wp_enqueue_script(
226 'wp_2fa_micro_modals',
227 script_url( 'micromodal', 'admin' ),
228 array(),
229 WP_2FA_VERSION,
230 true
231 );
232
233 enqueueSelect2Scripts();
234
235 if (\WP2FA\WP2FA::is_this_multisite()) {
236 enqueueMultiSelectScripts();
237 }
238
239 // Data array.
240 $data_array = array(
241 'ajaxURL' => admin_url( 'admin-ajax.php' ),
242 'roles' => \WP2FA\WP2FA::wp_2fa_get_roles(),
243 'nonce' => wp_create_nonce( 'wp-2fa-settings-nonce' ),
244 'codeValidatedHeading' => esc_html__( 'Congratulations', 'wp-2fa' ),
245 'codeValidatedText' => esc_html__( 'Your account just got more secure', 'wp-2fa' ),
246 'codeValidatedButton' => esc_html__( 'Close Wizard & Refresh', 'wp-2fa' ),
247 'processingText' => esc_html__( 'Processing Update', 'wp-2fa' ),
248 'email_sent_success' => esc_html__( 'Email successfully sent', 'wp-2fa' ),
249 'email_sent_failure' => esc_html__( 'Email delivery failed', 'wp-2fa' ),
250 'license_validation_in_progress' => esc_html__( 'Validating your license, please wait...', 'wp-2fa' )
251 );
252 wp_localize_script( 'wp_2fa_admin', 'wp2faData', $data_array );
253
254 $data_array = array(
255 'ajaxURL' => admin_url( 'admin-ajax.php' ),
256 'nonce' => wp_create_nonce( 'wp2fa-verify-wizard-page' ),
257 'codesPreamble' => esc_html__( 'These are the 2FA backup codes for the user', 'wp-2fa' ),
258 'readyText' => esc_html__( 'I\'m ready', 'wp-2fa' ),
259 'codeReSentText' => esc_html__( 'New code sent', 'wp-2fa' ),
260 );
261 wp_localize_script( 'wp_2fa_admin', 'wp2faWizardData', $data_array );
262
263 }
264
265 /**
266 * Enqueue multi select for multinetwork WP
267 *
268 * @return void
269 */
270 function enqueueMultiSelectScripts() {
271 wp_enqueue_script( 'multi-site-select', script_url( 'multi-site-select', 'admin' ), [ 'jquery', 'select2' ] );
272 }
273
274 /**
275 * Enqueue Select2 jQuery library
276 *
277 * @return void
278 */
279 function enqueueSelect2Scripts() {
280 wp_enqueue_style( 'select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css' );
281 wp_enqueue_script( 'select2', 'https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js', [ 'jquery' ] );
282 }
283
284 /**
285 * Enqueue styles for admin.
286 *
287 * @return void
288 */
289 function admin_styles() {
290
291 wp_enqueue_style(
292 'wp_2fa_admin',
293 style_url( 'admin-style', 'admin' ),
294 array(),
295 WP_2FA_VERSION
296 );
297
298 }
299
300 /**
301 * Add async/defer attributes to enqueued scripts that have the specified script_execution flag.
302 *
303 * @link https://core.trac.wordpress.org/ticket/12009
304 * @param string $tag The script tag.
305 * @param string $handle The script handle.
306 * @return string
307 */
308 function script_loader_tag( $tag, $handle ) {
309 $script_execution = wp_scripts()->get_data( $handle, 'script_execution' );
310
311 if ( ! $script_execution ) {
312 return $tag;
313 }
314
315 if ( 'async' !== $script_execution && 'defer' !== $script_execution ) {
316 return $tag;
317 }
318
319 // Abort adding async/defer for scripts that have this script as a dependency. _doing_it_wrong()?
320 foreach ( wp_scripts()->registered as $script ) {
321 if ( in_array( $handle, $script->deps, true ) ) {
322 return $tag;
323 }
324 }
325
326 // Add the attribute if it hasn't already been added.
327 if ( ! preg_match( ":\s$script_execution(=|>|\s):", $tag ) ) {
328 $tag = preg_replace( ':(?=></script>):', " $script_execution", $tag, 1 );
329 }
330
331 return $tag;
332 }
333