PluginProbe
Two Factor Authentication / 1.2.6
Two Factor Authentication v1.2.6
1.12.2 1.13.0 1.14.10 1.14.11 1.14.14 1.14.15 1.14.16 1.14.17 1.14.23 1.14.24 1.14.26 1.14.27 1.14.3 1.14.4 1.14.5 1.14.7 1.14.8 1.15.5 1.16.0 1.2.10 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 All 98 releases
two-factor-authentication / includes / tfa_frontend.php

tfa_frontend.php in Two Factor Authentication 1.2.6, at includes/tfa_frontend.php

283 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) die('Access denied.');
3
4 class TFA_Frontend {
5
6 private $mother;
7
8 public function __construct($mother) {
9
10 $this->mother = $mother;
11 add_action('wp_ajax_tfa_frontend', array($this, 'ajax'));
12 add_shortcode('twofactor_user_settings', array($this, 'tfa_user_settings_front'));
13 }
14
15 public function ajax(){
16 $tfa = $this->mother->getTFA();
17 global $current_user;
18
19 $return_array = array();
20
21 if (empty($_POST) || empty($_POST['subaction']) || !isset($_POST['nonce']) || !is_user_logged_in() || !wp_verify_nonce($_POST['nonce'], 'tfa_frontend_nonce')) die('Security check');
22
23 if('savesettings' == $_POST['subaction']) {
24 if (empty($_POST['settings']) || !is_string($_POST['settings'])) die;
25
26 parse_str($_POST['settings'], $posted_settings);
27
28 //Added
29 if(isset($posted_settings["tfa_enable_tfa"])) {
30 $tfa->changeEnableTFA($current_user->ID, $posted_settings["tfa_enable_tfa"]);
31 }
32
33 if(isset($posted_settings["tfa_algorithm_type"])) {
34 $old_algorithm = $tfa->getUserAlgorithm($current_user->ID);
35
36 if($old_algorithm != $posted_settings['tfa_algorithm_type'])
37 $tfa->changeUserAlgorithmTo($current_user->ID, $posted_settings['tfa_algorithm_type']);
38
39 //Re-fetch the algorithm type, url and private string
40 $variables = $this->tfa_fetch_assort_vars();
41
42 $return_array['qr'] = $this->mother->tfa_qr_code_url($variables['algorithm_type'], $variables['url'], $variables['tfa_priv_key']);
43 $return_array['al_type_disp'] = $this->tfa_algorithm_info($variables['algorithm_type']);
44 }
45
46 $return_array['result'] = 'saved';
47
48 echo json_encode($return_array);
49 }
50
51 die;
52 }
53
54 //Make the algorithm information string easier to update
55 public function tfa_algorithm_info($algorithm_type) {
56 $al_type_disp = strtoupper($algorithm_type);
57 $al_type_desc = ($algorithm_type == 'totp' ? __('a time based', SIMBA_TFA_TEXT_DOMAIN) : __('an event based', SIMBA_TFA_TEXT_DOMAIN));
58
59 return array('disp' => $al_type_disp, 'desc' => $al_type_desc);
60 }
61
62 /*
63 Make the assorted required variables more accessible for ajax
64 Returns: Site URl, private key, emergency codes, algorithm type
65 */
66 public function tfa_fetch_assort_vars(){
67 global $current_user;
68 $tfa = $this->mother->getTFA();
69
70 $url = preg_replace('/^https?:\/\//', '', site_url());
71
72 $tfa_priv_key_64 = get_user_meta($current_user->ID, 'tfa_priv_key_64', true);
73
74 if(!$tfa_priv_key_64)
75 $tfa_priv_key_64 = $tfa->addPrivateKey($current_user->ID);
76
77 $tfa_priv_key = trim($tfa->getPrivateKeyPlain($tfa_priv_key_64, $current_user->ID));
78
79 $algorithm_type = $tfa->getUserAlgorithm($current_user->ID);
80
81 return apply_filters('simba_tfa_fetch_assort_vars', array(
82 'url' => $url,
83 'tfa_priv_key_64' => $tfa_priv_key_64,
84 'tfa_priv_key' => $tfa_priv_key,
85 'emergency_str' => '<em>'.__('No emergency codes left. Sorry.', SIMBA_TFA_TEXT_DOMAIN).'</em>',
86 'algorithm_type' => $algorithm_type
87 ), $tfa, $current_user);
88 }
89
90 public function save_settings_button() {
91 echo '<button style="margin-left: 4px;margin-bottom: 10px" class="simbatfa_settings_save button button-primary">'.__('Save Settings', SIMBA_TFA_TEXT_DOMAIN).'</button>';
92 }
93
94 private function get_tfa() {
95 if (empty($this->tfa)) $this->tfa = $this->mother->getTFA();
96 }
97
98 public function settings_enable_or_disable_output() {
99 $this->save_settings_javascript_output();
100 global $current_user;
101 ?>
102 <div class="simbatfa_frontend_settings_box tfa_settings_form">
103 <p><?php $this->mother->tfaListEnableRadios($current_user->ID, true); ?></p>
104 <button style="margin-left: 4px;margin-bottom: 10px" class="button button-primary simbatfa_settings_save"><?php echo __('Save Settings', SIMBA_TFA_TEXT_DOMAIN); ?></button>
105 </div>
106 <?php
107 }
108
109 public function save_settings_javascript_output() {
110 static $is_already_added;
111 if (!empty($is_already_added)) return;
112 $is_already_added = true;
113 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
114 wp_register_script( 'jquery-blockui', SIMBA_TFA_PLUGIN_URL . '/includes/jquery.blockUI' . $suffix . '.js', array('jquery' ), '2.60' );
115 wp_enqueue_script('jquery-blockui');
116 add_action('wp_footer', array($this, 'wp_footer'));
117 }
118
119 public function wp_footer() {
120 $ajax_url = admin_url('admin-ajax.php');
121 // It's possible that FORCE_ADMIN_SSL will make that SSL, whilst the user is on the front-end having logged in over non-SSL - and as a result, their login cookies won't get sent, and they're not registered as logged in.
122 if (!is_admin() && substr(strtolower($ajax_url), 0, 6) == 'https:' && !is_ssl()) {
123 $also_try = 'http:'.substr($ajax_url, 6);
124 }
125 ?>
126
127 <script type="text/javascript">
128 var tfa_query_leaving = false;
129
130 // Prevent accidental leaving if there are unsaved settings
131 window.onbeforeunload = function(e) {
132 if (tfa_query_leaving) {
133 var ask = "<?php echo esc_js(__('You have unsaved settings.', SIMBA_TFA_TEXT_DOMAIN)); ?>";
134 e.returnValue = ask;
135 return ask;
136 }
137 }
138
139 jQuery(document).ready(function($) {
140 $(".tfa_settings_form input, .tfa_settings_form textarea, .tfa_settings_form select" ).change(function() {
141 tfa_query_leaving = true;
142 });
143
144 $(".tfa_settings_form input[name='simbatfa_delivery_type']").change(function() {
145 $(".tfa_third_party_holder").slideToggle();
146 });
147
148 //Save Settings
149 $(".simbatfa_settings_save").click(function() {
150
151 $.blockUI({ message: '<div style="margin: 8px;font-size:150%;"><?php echo esc_js(__('Saving...', SIMBA_TFA_TEXT_DOMAIN )); ?></div>' });
152
153 // https://stackoverflow.com/questions/10147149/how-can-i-override-jquerys-serialize-to-include-unchecked-checkboxes
154 var formData = $(".tfa_settings_form input, .tfa_settings_form textarea, .tfa_settings_form select").serialize();
155
156 // include unchecked checkboxes. use filter to only include unchecked boxes.
157 $.each($(".tfa_settings_form input[type=checkbox]")
158 .filter(function(idx){
159 return $(this).prop("checked") === false
160 }),
161 function(idx, el){
162 // attach matched element names to the formData with a chosen value.
163 var emptyVal = "0";
164 formData += "&" + $(el).attr("name") + "=" + emptyVal;
165 }
166 );
167
168 $.post('<?php echo esc_js($ajax_url);?>', {
169 action: "tfa_frontend",
170 subaction: "savesettings",
171 settings: formData,
172 nonce: "<?php echo wp_create_nonce("tfa_frontend_nonce");?>"
173 }, function(response) {
174 var settings_saved = false;
175 try {
176 var resp = $.parseJSON(response);
177 if (resp.hasOwnProperty('result')) {
178 settings_saved = true;
179 tfa_query_leaving = false;
180 }
181 if (resp.hasOwnProperty('qr')) {
182 $('.simbaotp_qr_container').data('qrcode', resp['qr']).empty().qrcode({
183 "render": "image",
184 "text": resp['qr'],
185 });
186 }
187 if (resp.hasOwnProperty('al_type_disp')) {
188 $("#al_type_name").html(resp['al_type_disp']['disp']);
189 $("#al_type_desc").html(resp['al_type_disp']['desc']);
190 }
191
192 } catch(err) {
193 console.log(err);
194 console.log(response);
195 <?php if (!isset($also_try)) { ?> alert("<?php echo esc_js(__('Response:', 'SIMBA_TFA_TEXT_DOMAIN')); ?> "+response);<?php } ?>
196 }
197 <?php if (isset($also_try)) { ?>
198 if (!settings_saved) {
199 $.post('<?php echo esc_js($also_try);?>', {
200 action: "tfa_frontend",
201 subaction: "savesettings",
202 settings: formData,
203 nonce: "<?php echo wp_create_nonce("tfa_frontend_nonce");?>"
204 }, function(response) {
205
206 try {
207 var resp = $.parseJSON(response);
208 if (resp.hasOwnProperty('result')) {
209 settings_saved = true;
210 tfa_query_leaving = false;
211 }
212 if (resp.hasOwnProperty('qr')) {
213 $('.simbaotp_qr_container').data('qrcode', resp['qr']).empty().qrcode({
214 "render": "image",
215 "text": resp['qr'],
216 });
217 }
218 if (resp.hasOwnProperty('al_type_disp')) {
219 $("#al_type_name").html(resp['al_type_disp']['disp']);
220 $("#al_type_desc").html(resp['al_type_disp']['desc']);
221 }
222
223 } catch(err) {
224 console.log(err);
225 console.log(response);
226 alert("<?php echo esc_js(__('Response:', 'SIMBA_TFA_TEXT_DOMAIN')); ?> "+response);
227 }
228 $.unblockUI();
229 });
230 } else {
231 $.unblockUI();
232 }
233 <?php } else { ?>
234 $.unblockUI();
235 <?php } ?>
236 });
237
238 });
239 });
240 </script>
241 <?php
242 }
243
244 /* Main Output function*/
245 public function tfa_user_settings_front($atts, $content = null){
246
247 if (!is_user_logged_in()) return '';
248
249 global $current_user;
250
251 // We want to print to buffer, since the shortcode API wants the value returned, not echoed
252 ob_start();
253
254 $this->get_tfa();
255
256 if(!$this->tfa->isActivatedForUser($current_user->ID)){
257 echo __('Two factor authentication is not available for your user.', SIMBA_TFA_TEXT_DOMAIN);
258 } else {
259
260 ?>
261
262 <div class="wrap" style="padding-bottom:10px">
263
264 <?php $this->mother->settings_intro_notices(); ?>
265
266 <?php $this->settings_enable_or_disable_output(); ?>
267
268 <?php $this->mother->current_codes_box(false); ?>
269
270 <?php $this->mother->advanced_settings_box(array($this, 'save_settings_button')); ?>
271
272 </div>
273
274 <?php $this->save_settings_javascript_output(); ?>
275
276 <?php
277 }
278
279 return ob_get_clean();
280
281 }
282 }
283