Google Authenticator – WordPress Two Factor Authentication (2FA) - Version 5.1.9

Version Description

Download this release

Release Info

Developer cyberlord92
Plugin Icon 128x128 Google Authenticator – WordPress Two Factor Authentication (2FA)
Version 5.1.9
Comparing to
See all releases

Code changes from version 5.1.8 to 5.1.9

class-customer-setup.php CHANGED
@@ -29,6 +29,9 @@ class Customer_Setup {
29
  public $customerKey;
30
  public $transactionId;
31
 
 
 
 
32
  function check_customer() {
33
  if ( ! MO2f_Utility::is_curl_installed() ) {
34
  $message = 'Please enable curl extension. <a href="admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mo2f_help">Click here</a> for the steps to enable curl or check Help & Troubleshooting.';
@@ -49,9 +52,9 @@ class Customer_Setup {
49
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
50
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
51
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
52
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
53
 
54
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
55
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
56
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
57
  'Content-Type: application/json',
@@ -115,7 +118,7 @@ class Customer_Setup {
115
  $customer_feature = "V3";
116
  }
117
 
118
- $query = '[WordPress 2 Factor Authentication Plugin: ' . $customer_feature . ' - V 5.1.8]: ' . $message;
119
 
120
  $content = '<div >First Name :' . $user->user_firstname . '<br><br>Last Name :' . $user->user_lastname . ' <br><br>Company :<a href="' . $_SERVER['SERVER_NAME'] . '" target="_blank" >' . $_SERVER['SERVER_NAME'] . '</a><br><br>Phone Number :' . $phone . '<br><br>Email :<a href="mailto:' . $fromEmail . '" target="_blank">' . $fromEmail . '</a><br><br>Query :' . $query . '</div>';
121
 
@@ -133,12 +136,12 @@ class Customer_Setup {
133
  ),
134
  );
135
  $field_string = json_encode( $fields );
136
-
137
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
138
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
139
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
140
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
141
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
142
 
143
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
144
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
@@ -168,8 +171,8 @@ class Customer_Setup {
168
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
169
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
170
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
171
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
172
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); // required for https urls
173
 
174
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
175
 
@@ -234,9 +237,9 @@ class Customer_Setup {
234
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
235
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
236
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
237
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
238
 
239
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
240
 
241
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
242
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
@@ -281,7 +284,7 @@ class Customer_Setup {
281
  $ch = curl_init( $url );
282
  $email = get_option( "mo2f_email" );
283
  $password = get_option( "mo2f_password" );
284
-
285
  $fields = array(
286
  'email' => $email,
287
  'password' => $password
@@ -292,10 +295,10 @@ class Customer_Setup {
292
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
293
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
294
 
295
-
296
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
297
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
298
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
299
 
300
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
301
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
@@ -316,8 +319,9 @@ class Customer_Setup {
316
  curl_setopt( $ch, CURLOPT_PROXYUSERPWD, get_option( "mo2f_proxy_username" ) . ':' . get_option( "mo2f_proxy_password" ) );
317
 
318
  }
319
-
320
  $content = curl_exec( $ch );
 
321
  if ( curl_errno( $ch ) ) {
322
  return null;
323
  }
@@ -384,9 +388,9 @@ class Customer_Setup {
384
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
385
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
386
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
387
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
388
 
389
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
390
 
391
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
392
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
@@ -450,8 +454,8 @@ class Customer_Setup {
450
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
451
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
452
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
453
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
454
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
455
 
456
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
457
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
@@ -554,9 +558,9 @@ class Customer_Setup {
554
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
555
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
556
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
557
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
558
 
559
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
560
 
561
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
562
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
@@ -615,7 +619,7 @@ class Customer_Setup {
615
  $customer_feature = "V3";
616
  }
617
 
618
- $query = '[WordPress 2 Factor Authentication Plugin: ' . $customer_feature . ' - V 5.1.8]: ' . $query;
619
  $fields = array(
620
  'firstName' => $user->user_firstname,
621
  'lastName' => $user->user_lastname,
@@ -625,14 +629,14 @@ class Customer_Setup {
625
  'query' => $query
626
  );
627
  $field_string = json_encode( $fields );
628
-
629
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false );
630
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
631
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
632
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
633
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
634
 
635
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
636
 
637
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
638
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
@@ -655,7 +659,7 @@ class Customer_Setup {
655
  }
656
 
657
  $content = curl_exec( $ch );
658
-
659
  if ( curl_errno( $ch ) ) {
660
  return null;
661
  }
29
  public $customerKey;
30
  public $transactionId;
31
 
32
+ private $auth_mode = 2; // miniorange test or not
33
+ private $https_mode = false; // website http or https
34
+
35
  function check_customer() {
36
  if ( ! MO2f_Utility::is_curl_installed() ) {
37
  $message = 'Please enable curl extension. <a href="admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mo2f_help">Click here</a> for the steps to enable curl or check Help & Troubleshooting.';
52
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
53
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
54
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
55
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
56
 
57
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
58
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
59
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
60
  'Content-Type: application/json',
118
  $customer_feature = "V3";
119
  }
120
 
121
+ $query = '[WordPress 2 Factor Authentication Plugin: ' . $customer_feature . ' - V 5.1.9]: ' . $message;
122
 
123
  $content = '<div >First Name :' . $user->user_firstname . '<br><br>Last Name :' . $user->user_lastname . ' <br><br>Company :<a href="' . $_SERVER['SERVER_NAME'] . '" target="_blank" >' . $_SERVER['SERVER_NAME'] . '</a><br><br>Phone Number :' . $phone . '<br><br>Email :<a href="mailto:' . $fromEmail . '" target="_blank">' . $fromEmail . '</a><br><br>Query :' . $query . '</div>';
124
 
136
  ),
137
  );
138
  $field_string = json_encode( $fields );
139
+
140
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
141
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
142
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
143
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
144
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
145
 
146
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
147
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
171
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
172
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
173
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
174
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode );
175
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode ); // required for https urls
176
 
177
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
178
 
237
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
238
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
239
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
240
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
241
 
242
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
243
 
244
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
245
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
284
  $ch = curl_init( $url );
285
  $email = get_option( "mo2f_email" );
286
  $password = get_option( "mo2f_password" );
287
+
288
  $fields = array(
289
  'email' => $email,
290
  'password' => $password
295
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
296
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
297
 
298
+
299
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
300
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
301
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
302
 
303
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
304
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
319
  curl_setopt( $ch, CURLOPT_PROXYUSERPWD, get_option( "mo2f_proxy_username" ) . ':' . get_option( "mo2f_proxy_password" ) );
320
 
321
  }
322
+
323
  $content = curl_exec( $ch );
324
+
325
  if ( curl_errno( $ch ) ) {
326
  return null;
327
  }
388
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
389
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
390
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
391
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
392
 
393
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
394
 
395
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
396
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
454
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
455
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
456
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
457
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
458
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
459
 
460
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
461
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
558
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
559
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
560
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
561
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
562
 
563
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
564
 
565
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
566
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
619
  $customer_feature = "V3";
620
  }
621
 
622
+ $query = '[WordPress 2 Factor Authentication Plugin: ' . $customer_feature . ' - V 5.1.9]: ' . $query;
623
  $fields = array(
624
  'firstName' => $user->user_firstname,
625
  'lastName' => $user->user_lastname,
629
  'query' => $query
630
  );
631
  $field_string = json_encode( $fields );
632
+
633
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false );
634
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
635
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
636
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
637
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
638
 
639
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
640
 
641
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
642
  curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
659
  }
660
 
661
  $content = curl_exec( $ch );
662
+
663
  if ( curl_errno( $ch ) ) {
664
  return null;
665
  }
class-miniorange-2-factor-login.php CHANGED
@@ -108,6 +108,7 @@ class Miniorange_Mobile_Login {
108
  }
109
 
110
  function remove_current_activity($session_id) {
 
111
  $session_variables = array(
112
  'mo2f_current_user_id',
113
  'mo2f_1stfactor_status',
@@ -152,7 +153,22 @@ class Miniorange_Mobile_Login {
152
 
153
  MO2f_Utility::unset_session_variables( $session_variables );
154
  MO2f_Utility::unset_cookie_variables( $cookie_variables );
155
- MO2f_Utility::unset_temp_user_details_in_table( $temp_table_variables, $session_id, "destroy" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
  }
157
 
158
  function custom_login_enqueue_scripts() {
@@ -161,8 +177,8 @@ class Miniorange_Mobile_Login {
161
  }
162
 
163
  function mo_2_factor_hide_login() {
164
- wp_register_style( 'hide-login', plugins_url( 'includes/css/hide-login.css?version=5.1.8', __FILE__ ) );
165
- wp_register_style( 'bootstrap', plugins_url( 'includes/css/bootstrap.min.css?version=5.1.8', __FILE__ ) );
166
 
167
  wp_enqueue_style( 'hide-login' );
168
  wp_enqueue_style( 'bootstrap' );
@@ -224,7 +240,7 @@ class Miniorange_Mobile_Login {
224
  }
225
 
226
  function mo_2_factor_show_login_with_password_when_phonelogin_enabled() {
227
- wp_register_style( 'show-login', plugins_url( 'includes/css/show-login.css?version=5.1.8', __FILE__ ) );
228
  wp_enqueue_style( 'show-login' );
229
  }
230
 
@@ -246,9 +262,9 @@ class Miniorange_Mobile_Login {
246
 
247
  function mo_2_factor_show_login() {
248
  if ( get_option( 'mo2f_enable_login_with_2nd_factor' ) ) {
249
- wp_register_style( 'show-login', plugins_url( 'includes/css/hide-login-form.css?version=5.1.8', __FILE__ ) );
250
  } else {
251
- wp_register_style( 'show-login', plugins_url( 'includes/css/show-login.css?version=5.1.8', __FILE__ ) );
252
  }
253
  wp_enqueue_style( 'show-login' );
254
  }
108
  }
109
 
110
  function remove_current_activity($session_id) {
111
+ global $Mo2fdbQueries;
112
  $session_variables = array(
113
  'mo2f_current_user_id',
114
  'mo2f_1stfactor_status',
153
 
154
  MO2f_Utility::unset_session_variables( $session_variables );
155
  MO2f_Utility::unset_cookie_variables( $cookie_variables );
156
+
157
+ $key = get_option( 'mo2f_encryption_key' );
158
+
159
+ $session_id = MO2f_Utility::decrypt_data( $session_id, $key );
160
+ $Mo2fdbQueries->save_user_login_details( $session_id, array(
161
+
162
+ 'mo2f_current_user_id' => '',
163
+ 'mo2f_login_message' => '',
164
+ 'mo2f_1stfactor_status' => '',
165
+ 'mo2f_transactionId' => '',
166
+ 'mo_2_factor_kba_questions' => '',
167
+ 'mo2f_rba_status' => '',
168
+ 'ts_created' => ''
169
+
170
+ ) );
171
+
172
  }
173
 
174
  function custom_login_enqueue_scripts() {
177
  }
178
 
179
  function mo_2_factor_hide_login() {
180
+ wp_register_style( 'hide-login', plugins_url( 'includes/css/hide-login.css?version=5.1.9', __FILE__ ) );
181
+ wp_register_style( 'bootstrap', plugins_url( 'includes/css/bootstrap.min.css?version=5.1.9', __FILE__ ) );
182
 
183
  wp_enqueue_style( 'hide-login' );
184
  wp_enqueue_style( 'bootstrap' );
240
  }
241
 
242
  function mo_2_factor_show_login_with_password_when_phonelogin_enabled() {
243
+ wp_register_style( 'show-login', plugins_url( 'includes/css/show-login.css?version=5.1.9', __FILE__ ) );
244
  wp_enqueue_style( 'show-login' );
245
  }
246
 
262
 
263
  function mo_2_factor_show_login() {
264
  if ( get_option( 'mo2f_enable_login_with_2nd_factor' ) ) {
265
+ wp_register_style( 'show-login', plugins_url( 'includes/css/hide-login-form.css?version=5.1.9', __FILE__ ) );
266
  } else {
267
+ wp_register_style( 'show-login', plugins_url( 'includes/css/show-login.css?version=5.1.9', __FILE__ ) );
268
  }
269
  wp_enqueue_style( 'show-login' );
270
  }
class-miniorange-2-factor-pass2fa-login.php CHANGED
@@ -536,7 +536,7 @@ class Miniorange_Password_2Factor_Login {
536
  }
537
 
538
  function remove_current_activity($session_id) {
539
-
540
  $session_variables = array(
541
  'mo2f_current_user_id',
542
  'mo2f_1stfactor_status',
@@ -581,8 +581,21 @@ class Miniorange_Password_2Factor_Login {
581
 
582
  MO2f_Utility::unset_session_variables( $session_variables );
583
  MO2f_Utility::unset_cookie_variables( $cookie_variables );
584
- MO2f_Utility::unset_temp_user_details_in_table( $temp_table_variables , $session_id, "destroy" );
 
 
 
 
 
 
 
 
 
 
 
585
 
 
 
586
 
587
  }
588
 
@@ -950,7 +963,8 @@ class Miniorange_Password_2Factor_Login {
950
  $session_id = MO2f_Utility::random_str(20);
951
  $Mo2fdbQueries->insert_user_login_session($session_id);
952
 
953
- $key = get_option('mo2f_customer_token');
 
954
  $session_id_encrypt = MO2f_Utility::encrypt_data($session_id, $key);
955
  return $session_id_encrypt;
956
  }
@@ -969,7 +983,7 @@ class Miniorange_Password_2Factor_Login {
969
  $is_2fa_enabled_for_users = get_option( 'mo2f_enable_2fa_for_users' );
970
  $is_2fa_enabled_by_users = get_option( 'mo2f_enable_2fa' );
971
 
972
- //$enabled_2fa_byusers = $Mo2fdbQueries->get_user_detail( 'mo2f_2factor_enable_2fa_byusers', $currentuser->ID );
973
  //if ( $enabled_2fa_byusers ) {
974
 
975
  if ( $is_customer_admin || ( ! $is_customer_admin && $is_2fa_enabled_for_users && $is_2fa_enabled_by_users ) ) {
536
  }
537
 
538
  function remove_current_activity($session_id) {
539
+ global $Mo2fdbQueries;
540
  $session_variables = array(
541
  'mo2f_current_user_id',
542
  'mo2f_1stfactor_status',
581
 
582
  MO2f_Utility::unset_session_variables( $session_variables );
583
  MO2f_Utility::unset_cookie_variables( $cookie_variables );
584
+
585
+ $key = get_option( 'mo2f_encryption_key' );
586
+ $session_id = MO2f_Utility::decrypt_data( $session_id, $key );
587
+ $Mo2fdbQueries->save_user_login_details( $session_id, array(
588
+
589
+ 'mo2f_current_user_id' => '',
590
+ 'mo2f_login_message' => '',
591
+ 'mo2f_1stfactor_status' => '',
592
+ 'mo2f_transactionId' => '',
593
+ 'mo_2_factor_kba_questions' => '',
594
+ 'mo2f_rba_status' => '',
595
+ 'ts_created' => ''
596
 
597
+ ) );
598
+
599
 
600
  }
601
 
963
  $session_id = MO2f_Utility::random_str(20);
964
  $Mo2fdbQueries->insert_user_login_session($session_id);
965
 
966
+
967
+ $key = get_option( 'mo2f_encryption_key' );
968
  $session_id_encrypt = MO2f_Utility::encrypt_data($session_id, $key);
969
  return $session_id_encrypt;
970
  }
983
  $is_2fa_enabled_for_users = get_option( 'mo2f_enable_2fa_for_users' );
984
  $is_2fa_enabled_by_users = get_option( 'mo2f_enable_2fa' );
985
 
986
+
987
  //if ( $enabled_2fa_byusers ) {
988
 
989
  if ( $is_customer_admin || ( ! $is_customer_admin && $is_2fa_enabled_for_users && $is_2fa_enabled_by_users ) ) {
class-miniorange-2-factor-user-registration.php CHANGED
@@ -30,7 +30,7 @@ class Miniorange_User_Register {
30
  }
31
 
32
  function plugin_settings_style() {
33
- wp_enqueue_style( 'mo_2_factor_admin_settings_style', plugins_url( 'includes/css/style_settings.css?version=5.1.8', __FILE__ ) );
34
  }
35
 
36
  function mo_auth_success_message() {
30
  }
31
 
32
  function plugin_settings_style() {
33
+ wp_enqueue_style( 'mo_2_factor_admin_settings_style', plugins_url( 'includes/css/style_settings.css?version=5.1.9', __FILE__ ) );
34
  }
35
 
36
  function mo_auth_success_message() {
class-rba-attributes.php CHANGED
@@ -23,7 +23,10 @@
23
  * Contains Request Calls to Customer service.
24
  **/
25
  class Miniorange_Rba_Attributes {
26
-
 
 
 
27
  function mo2f_collect_attributes( $useremail, $rba_attributes ) {
28
 
29
  if ( ! MO2f_Utility::is_curl_installed() ) {
@@ -76,8 +79,8 @@ class Miniorange_Rba_Attributes {
76
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
77
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
78
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
79
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
80
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); // required for https urls
81
 
82
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
83
 
@@ -123,9 +126,9 @@ class Miniorange_Rba_Attributes {
123
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
124
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
125
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
126
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
127
 
128
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
129
 
130
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
131
  curl_setopt( $ch, CURLOPT_HTTPHEADER, $http_header_array );
@@ -210,7 +213,7 @@ class Miniorange_Rba_Attributes {
210
  return $this->make_curl_call( $url, $field_string, $http_header_array );
211
  }
212
 
213
- function mo2f_google_auth_service( $useremail ) {
214
 
215
  if ( ! MO2f_Utility::is_curl_installed() ) {
216
  return $this->get_curl_error_message();
@@ -220,7 +223,8 @@ class Miniorange_Rba_Attributes {
220
  $customerKey = get_option( 'mo2f_customerKey' );
221
  $field_string = array(
222
  'customerKey' => $customerKey,
223
- 'username' => $useremail
 
224
  );
225
 
226
  $http_header_array = $this->get_http_header_array();
23
  * Contains Request Calls to Customer service.
24
  **/
25
  class Miniorange_Rba_Attributes {
26
+
27
+ private $auth_mode = 2; // miniorange test or not
28
+ private $https_mode = false; // website http or https
29
+
30
  function mo2f_collect_attributes( $useremail, $rba_attributes ) {
31
 
32
  if ( ! MO2f_Utility::is_curl_installed() ) {
79
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
80
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
81
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
82
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode );
83
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode ); // required for https urls
84
 
85
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
86
 
126
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
127
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
128
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
129
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
130
 
131
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
132
 
133
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
134
  curl_setopt( $ch, CURLOPT_HTTPHEADER, $http_header_array );
213
  return $this->make_curl_call( $url, $field_string, $http_header_array );
214
  }
215
 
216
+ function mo2f_google_auth_service( $useremail, $googleAuthenticatorName="" ) {
217
 
218
  if ( ! MO2f_Utility::is_curl_installed() ) {
219
  return $this->get_curl_error_message();
223
  $customerKey = get_option( 'mo2f_customerKey' );
224
  $field_string = array(
225
  'customerKey' => $customerKey,
226
+ 'username' => $useremail,
227
+ 'googleAuthenticatorName' => $googleAuthenticatorName
228
  );
229
 
230
  $http_header_array = $this->get_http_header_array();
class-two-factor-setup.php CHANGED
@@ -25,7 +25,8 @@
25
  class Two_Factor_Setup {
26
 
27
  public $email;
28
-
 
29
  function check_mobile_status( $tId ) {
30
 
31
  if ( ! MO2f_Utility::is_curl_installed() ) {
@@ -79,8 +80,8 @@ class Two_Factor_Setup {
79
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
80
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
81
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
82
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
83
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); // required for https urls
84
 
85
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
86
 
@@ -123,13 +124,14 @@ class Two_Factor_Setup {
123
  }
124
 
125
  $ch = curl_init( $url );
 
126
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false );
127
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
128
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
129
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
130
- curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
131
 
132
- curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); # required for https urls
133
 
134
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
135
  curl_setopt( $ch, CURLOPT_HTTPHEADER, $http_header_array );
25
  class Two_Factor_Setup {
26
 
27
  public $email;
28
+ private $auth_mode = 2; // miniorange test or not
29
+ private $https_mode = false; // website http or https
30
  function check_mobile_status( $tId ) {
31
 
32
  if ( ! MO2f_Utility::is_curl_installed() ) {
80
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
81
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
82
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
83
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode );
84
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode ); // required for https urls
85
 
86
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
87
 
124
  }
125
 
126
  $ch = curl_init( $url );
127
+
128
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false );
129
  curl_setopt( $ch, CURLOPT_ENCODING, "" );
130
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
131
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
132
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, $this->auth_mode );
133
 
134
+ curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, $this->https_mode ); # required for https urls
135
 
136
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
137
  curl_setopt( $ch, CURLOPT_HTTPHEADER, $http_header_array );
class-utility.php CHANGED
@@ -123,7 +123,8 @@ class MO2f_Utility {
123
 
124
  // setting session values
125
  $_SESSION[$variable] = $value;
126
- $key = get_option( 'mo2f_customer_token' );
 
127
  // setting cookie values
128
  if(is_array($value)){
129
  if($variable == 'mo_2_factor_kba_questions'){
@@ -202,7 +203,8 @@ class MO2f_Utility {
202
  if ( isset( $_SESSION[ $variable ] ) && ! empty( $_SESSION[ $variable ] ) ) {
203
  return $_SESSION[ $variable ];
204
  } else {
205
- $key = get_option( 'mo2f_customer_token' );
 
206
  $cookie_value = false;
207
 
208
  if ( $variable == 'mo2f_rba_status' ) {
@@ -258,7 +260,8 @@ class MO2f_Utility {
258
  * @return string
259
  */
260
  public static function mo2f_get_cookie_values( $cookiename ) {
261
- $key = get_option( 'mo2f_customer_token' );
 
262
  if ( isset( $_COOKIE[ $cookiename ] ) ) {
263
  $decrypted_data = MO2f_Utility::decrypt_data( base64_decode( $_COOKIE[ $cookiename ] ), $key );
264
  if ( $decrypted_data ) {
@@ -292,14 +295,16 @@ class MO2f_Utility {
292
  * @return string
293
  */
294
  public static function mo2f_set_cookie_values( $cookiename, $cookievalue ) {
295
- $key = get_option( 'mo2f_customer_token' );
 
296
 
297
  $current_time = new DateTime( 'now' );
298
  $current_time = $current_time->format( 'Y-m-d H:i:sP' );
299
  $cookievalue = $cookievalue . '&' . $current_time;
300
 
301
  $cookievalue_encrypted = MO2f_Utility::encrypt_data( $cookievalue, $key );
302
- setcookie( $cookiename, base64_encode( $cookievalue_encrypted ) );
 
303
 
304
  }
305
 
@@ -352,12 +357,12 @@ class MO2f_Utility {
352
  if ( gettype( $variables ) == "array" ) {
353
  foreach ( $variables as $variable ) {
354
  if ( isset( $_COOKIE[ $variable ] ) ) {
355
- setcookie( $variable, '', time() - 3600 );
356
  }
357
  }
358
  } else {
359
  if ( isset( $_COOKIE[ $variables ] ) ) {
360
- setcookie( $variables, '', time() - 3600 );
361
  }
362
  }
363
 
@@ -375,7 +380,8 @@ class MO2f_Utility {
375
 
376
  global $Mo2fdbQueries;
377
 
378
- $key = get_option( 'mo2f_customer_token' );
 
379
  $session_id = MO2f_Utility::decrypt_data( $session_id, $key );
380
 
381
  if($command == "destroy"){
123
 
124
  // setting session values
125
  $_SESSION[$variable] = $value;
126
+
127
+ $key = get_option( 'mo2f_encryption_key' );
128
  // setting cookie values
129
  if(is_array($value)){
130
  if($variable == 'mo_2_factor_kba_questions'){
203
  if ( isset( $_SESSION[ $variable ] ) && ! empty( $_SESSION[ $variable ] ) ) {
204
  return $_SESSION[ $variable ];
205
  } else {
206
+ // $key = get_option( 'mo2f_customer_token' );
207
+ $key = get_option( 'mo2f_encryption_key' );
208
  $cookie_value = false;
209
 
210
  if ( $variable == 'mo2f_rba_status' ) {
260
  * @return string
261
  */
262
  public static function mo2f_get_cookie_values( $cookiename ) {
263
+
264
+ $key = get_option( 'mo2f_encryption_key' );
265
  if ( isset( $_COOKIE[ $cookiename ] ) ) {
266
  $decrypted_data = MO2f_Utility::decrypt_data( base64_decode( $_COOKIE[ $cookiename ] ), $key );
267
  if ( $decrypted_data ) {
295
  * @return string
296
  */
297
  public static function mo2f_set_cookie_values( $cookiename, $cookievalue ) {
298
+
299
+ $key = get_option( 'mo2f_encryption_key' );
300
 
301
  $current_time = new DateTime( 'now' );
302
  $current_time = $current_time->format( 'Y-m-d H:i:sP' );
303
  $cookievalue = $cookievalue . '&' . $current_time;
304
 
305
  $cookievalue_encrypted = MO2f_Utility::encrypt_data( $cookievalue, $key );
306
+ // setcookie( $cookiename, base64_encode( $cookievalue_encrypted ) );
307
+ setcookie( $cookiename, base64_encode( $cookievalue_encrypted ),NULL,NULL,NULL,NULL, TRUE );
308
 
309
  }
310
 
357
  if ( gettype( $variables ) == "array" ) {
358
  foreach ( $variables as $variable ) {
359
  if ( isset( $_COOKIE[ $variable ] ) ) {
360
+ setcookie( $variable, '', time() - 3600,NULL,NULL,NULL, TRUE );
361
  }
362
  }
363
  } else {
364
  if ( isset( $_COOKIE[ $variables ] ) ) {
365
+ setcookie( $variables, '', time() - 3600,NULL,NULL,NULL, TRUE );
366
  }
367
  }
368
 
380
 
381
  global $Mo2fdbQueries;
382
 
383
+
384
+ $key = get_option( 'mo2f_encryption_key' );
385
  $session_id = MO2f_Utility::decrypt_data( $session_id, $key );
386
 
387
  if($command == "destroy"){
database/database_functions.php CHANGED
@@ -87,6 +87,38 @@ class Mo2fDB {
87
 
88
  }
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  function insert_user( $user_id ) {
92
  global $wpdb;
@@ -218,11 +250,11 @@ class Mo2fDB {
218
  return $value == '' ? '' : $value[ $column_name ];
219
  }
220
 
221
- function delete_user_login_sessions( ) {
222
  global $wpdb;
223
  $wpdb->query(
224
  "DELETE FROM " . $this->userLoginInfoTable . "
225
- WHERE 1;"
226
  );
227
 
228
  return;
87
 
88
  }
89
 
90
+ function database_table_issue(){
91
+
92
+ global $wpdb;
93
+ $tableName = $this->userLoginInfoTable;
94
+
95
+ if($wpdb->get_var("show tables like '$tableName'") != $tableName) {
96
+
97
+ $sql = "CREATE TABLE IF NOT EXISTS " . $tableName . " (
98
+ `session_id` MEDIUMTEXT NOT NULL,
99
+ `mo2f_login_message` VARCHAR(500) NOT NULL ,
100
+ `mo2f_current_user_id` INT(50) NOT NULL ,
101
+ `mo2f_1stfactor_status` VARCHAR(100) NOT NULL ,
102
+ `mo_2factor_login_status` VARCHAR(100) NOT NULL ,
103
+ `mo2f_transactionId` VARCHAR(100) NOT NULL ,
104
+ `mo_2_factor_kba_questions` LONGTEXT NOT NULL ,
105
+ `mo2f_rba_status` LONGTEXT NOT NULL ,
106
+ `ts_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
107
+ PRIMARY KEY (`session_id`(500)));";
108
+
109
+ dbDelta( $sql );
110
+ }
111
+
112
+ $check_if_column_exists = $this->check_if_column_exists( "user_login_info_table", "mo_2factor_login_status" );
113
+
114
+ if ( ! $check_if_column_exists ) {
115
+ $query = "ALTER TABLE `$tableName` ADD COLUMN `mo_2factor_login_status` VARCHAR(100) NOT NULL";
116
+ $this->execute_add_column( $query );
117
+
118
+ }
119
+
120
+ }
121
+
122
 
123
  function insert_user( $user_id ) {
124
  global $wpdb;
250
  return $value == '' ? '' : $value[ $column_name ];
251
  }
252
 
253
+ function delete_user_login_sessions($session_id ) {
254
  global $wpdb;
255
  $wpdb->query(
256
  "DELETE FROM " . $this->userLoginInfoTable . "
257
+ WHERE session_id='$session_id';"
258
  );
259
 
260
  return;
includes/css/bootstrap-tour-standalone.css ADDED
@@ -0,0 +1,764 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ========================================================================
2
+ * bootstrap-tour - v0.12.0
3
+ * http://bootstraptour.com
4
+ * ========================================================================
5
+ * Copyright 2012-2017 Ulrich Sossou
6
+ *
7
+ * ========================================================================
8
+ * Licensed under the MIT License (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * https://opensource.org/licenses/MIT
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ * ========================================================================
20
+ */
21
+
22
+ .mo2f_tour_btn {
23
+ display: inline-block;
24
+ font-weight: normal;
25
+ text-align: center;
26
+ white-space: nowrap;
27
+ vertical-align: middle;
28
+ user-select: none;
29
+ border: 1px solid transparent;
30
+ padding: 0.5rem 0.75rem;
31
+ font-size: 1rem;
32
+ line-height: 1.25;
33
+ border-radius: 0.25rem;
34
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; }
35
+ .mo2f_tour_btn:focus, .mo2f_tour_btn:hover {
36
+ text-decoration: none; }
37
+ .mo2f_tour_btn:focus, .mo2f_tour_btn.focus {
38
+ outline: 0;
39
+ box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25); }
40
+ .mo2f_tour_btn.disabled, .mo2f_tour_btn:disabled {
41
+ opacity: .65; }
42
+ .mo2f_tour_btn:active, .mo2f_tour_btn.active {
43
+ background-image: none; }
44
+
45
+ a.mo2f_tour_btn.disabled,
46
+ fieldset[disabled] a.mo2f_tour_btn {
47
+ pointer-events: none; }
48
+
49
+ .mo2f_tour_btn-primary {
50
+ color: #fff;
51
+ background-color: #007bff;
52
+ border-color: #007bff; }
53
+ .mo2f_tour_btn-primary:hover {
54
+ color: #fff;
55
+ background-color: #0069d9;
56
+ border-color: #0062cc; }
57
+ .mo2f_tour_btn-primary:focus, .mo2f_tour_btn-primary.focus {
58
+ box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.5); }
59
+ .mo2f_tour_btn-primary.disabled, .mo2f_tour_btn-primary:disabled {
60
+ background-color: #007bff;
61
+ border-color: #007bff; }
62
+ .mo2f_tour_btn-primary:active, .mo2f_tour_btn-primary.active,
63
+ .show > .mo2f_tour_btn-primary.dropdown-toggle {
64
+ background-color: #0069d9;
65
+ background-image: none;
66
+ border-color: #0062cc; }
67
+
68
+ .mo2f_tour_btn-secondary {
69
+ color: #fff;
70
+ background-color: #007902;
71
+ border-color: #868e96;
72
+ }
73
+ .mo2f_tour_btn_end-secondary {
74
+ background: #00A0D2;
75
+ border-color: #0073AA;
76
+ box-shadow: 0 1px 0 rgba(120, 200, 230, .5) inset, 0 1px 0 rgba(0, 0, 0, .15);
77
+ color: #FFF;
78
+ text-decoration: none;
79
+ cursor: pointer;
80
+ border-width: 1px;
81
+ border-style: solid;
82
+ border-radius: 3px;
83
+ white-space: nowrap;
84
+ box-sizing: border-box;
85
+ line-height: 28px;
86
+ padding: 0 12px;
87
+ font-size: 13px
88
+ }
89
+ .mo2f_tour_btn_next-success {
90
+ background: #00A0D2;
91
+ background-color:#5cb85c;border-color:#4cae4c;
92
+ box-shadow: 0 1px 0 rgba(120, 200, 230, .5) inset, 0 1px 0 rgba(0, 0, 0, .15);
93
+ color: #FFF;
94
+ text-decoration: none;
95
+ cursor: pointer;
96
+ border-width: 1px;
97
+ border-style: solid;
98
+ border-radius: 3px;
99
+ white-space: nowrap;
100
+ box-sizing: border-box;
101
+ line-height: 28px;
102
+ padding: 0 12px;
103
+ font-size: 13px;
104
+ }
105
+ .mo2f_tour_btn-secondary:hover {
106
+ color: #fff;
107
+ background-color: #727b84;
108
+ border-color: #6c757d; }
109
+
110
+ .mo2f_tour_btn-secondary:focus, .mo2f_tour_btn-secondary.focus {
111
+ box-shadow: 0 0 0 3px rgba(134, 142, 150, 0.5); }
112
+ .mo2f_tour_btn-secondary.disabled, .mo2f_tour_btn-secondary:disabled {
113
+ background-color: #868e96;
114
+ border-color: #868e96; }
115
+ .mo2f_tour_btn-secondary:active, .mo2f_tour_btn-secondary.active,
116
+ .show > .mo2f_tour_btn-secondary.dropdown-toggle {
117
+ background-color: #727b84;
118
+ background-image: none;
119
+ border-color: #6c757d; }
120
+
121
+ .mo2f_tour_btn-success {
122
+ color: #fff;
123
+ background-color: #28a745;
124
+ border-color: #28a745; }
125
+ .mo2f_tour_btn-success:hover {
126
+ color: #fff;
127
+ background-color: #218838;
128
+ border-color: #1e7e34; }
129
+ .mo2f_tour_btn-success:focus, .mo2f_tour_btn-success.focus {
130
+ box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.5); }
131
+ .mo2f_tour_btn-success.disabled, .mo2f_tour_btn-success:disabled {
132
+ background-color: #28a745;
133
+ border-color: #28a745; }
134
+ .mo2f_tour_btn-success:active, .mo2f_tour_btn-success.active,
135
+ .show > .mo2f_tour_btn-success.dropdown-toggle {
136
+ background-color: #218838;
137
+ background-image: none;
138
+ border-color: #1e7e34; }
139
+
140
+ .mo2f_tour_btn-info {
141
+ color: #fff;
142
+ background-color: #17a2b8;
143
+ border-color: #17a2b8; }
144
+ .mo2f_tour_btn-info:hover {
145
+ color: #fff;
146
+ background-color: #138496;
147
+ border-color: #117a8b; }
148
+ .mo2f_tour_btn-info:focus, .mo2f_tour_btn-info.focus {
149
+ box-shadow: 0 0 0 3px rgba(23, 162, 184, 0.5); }
150
+ .mo2f_tour_btn-info.disabled, .mo2f_tour_btn-info:disabled {
151
+ background-color: #17a2b8;
152
+ border-color: #17a2b8; }
153
+ .mo2f_tour_btn-info:active, .mo2f_tour_btn-info.active,
154
+ .show > .mo2f_tour_btn-info.dropdown-toggle {
155
+ background-color: #138496;
156
+ background-image: none;
157
+ border-color: #117a8b; }
158
+
159
+ .mo2f_tour_btn-warning {
160
+ color: #111;
161
+ background-color: #ffc107;
162
+ border-color: #ffc107; }
163
+ .mo2f_tour_btn-warning:hover {
164
+ color: #111;
165
+ background-color: #e0a800;
166
+ border-color: #d39e00; }
167
+ .mo2f_tour_btn-warning:focus, .mo2f_tour_btn-warning.focus {
168
+ box-shadow: 0 0 0 3px rgba(255, 193, 7, 0.5); }
169
+ .mo2f_tour_btn-warning.disabled, .mo2f_tour_btn-warning:disabled {
170
+ background-color: #ffc107;
171
+ border-color: #ffc107; }
172
+ .mo2f_tour_btn-warning:active, .mo2f_tour_btn-warning.active,
173
+ .show > .mo2f_tour_btn-warning.dropdown-toggle {
174
+ background-color: #e0a800;
175
+ background-image: none;
176
+ border-color: #d39e00; }
177
+
178
+ .mo2f_tour_btn-danger {
179
+ color: #fff;
180
+ background-color: #dc3545;
181
+ border-color: #dc3545; }
182
+ .mo2f_tour_btn-danger:hover {
183
+ color: #fff;
184
+ background-color: #c82333;
185
+ border-color: #bd2130; }
186
+ .mo2f_tour_btn-danger:focus, .mo2f_tour_btn-danger.focus {
187
+ box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.5); }
188
+ .mo2f_tour_btn-danger.disabled, .mo2f_tour_btn-danger:disabled {
189
+ background-color: #dc3545;
190
+ border-color: #dc3545; }
191
+ .mo2f_tour_btn-danger:active, .mo2f_tour_btn-danger.active,
192
+ .show > .mo2f_tour_btn-danger.dropdown-toggle {
193
+ background-color: #c82333;
194
+ background-image: none;
195
+ border-color: #bd2130; }
196
+
197
+ .mo2f_tour_btn-light {
198
+ color: #111;
199
+ background-color: #f8f9fa;
200
+ border-color: #f8f9fa; }
201
+ .mo2f_tour_btn-light:hover {
202
+ color: #111;
203
+ background-color: #e2e6ea;
204
+ border-color: #dae0e5; }
205
+ .mo2f_tour_btn-light:focus, .mo2f_tour_btn-light.focus {
206
+ box-shadow: 0 0 0 3px rgba(248, 249, 250, 0.5); }
207
+ .mo2f_tour_btn-light.disabled, .mo2f_tour_btn-light:disabled {
208
+ background-color: #f8f9fa;
209
+ border-color: #f8f9fa; }
210
+ .mo2f_tour_btn-light:active, .mo2f_tour_btn-light.active,
211
+ .show > .mo2f_tour_btn-light.dropdown-toggle {
212
+ background-color: #e2e6ea;
213
+ background-image: none;
214
+ border-color: #dae0e5; }
215
+
216
+ .mo2f_tour_btn-dark {
217
+ color: #fff;
218
+ background-color: #343a40;
219
+ border-color: #343a40; }
220
+ .mo2f_tour_btn-dark:hover {
221
+ color: #fff;
222
+ background-color: #23272b;
223
+ border-color: #1d2124; }
224
+ .mo2f_tour_btn-dark:focus, .mo2f_tour_btn-dark.focus {
225
+ box-shadow: 0 0 0 3px rgba(52, 58, 64, 0.5); }
226
+ .mo2f_tour_btn-dark.disabled, .mo2f_tour_btn-dark:disabled {
227
+ background-color: #343a40;
228
+ border-color: #343a40; }
229
+ .mo2f_tour_btn-dark:active, .mo2f_tour_btn-dark.active,
230
+ .show > .mo2f_tour_btn-dark.dropdown-toggle {
231
+ background-color: #23272b;
232
+ background-image: none;
233
+ border-color: #1d2124; }
234
+
235
+ .mo2f_tour_btn-outline-primary {
236
+ color: #007bff;
237
+ background-color: transparent;
238
+ background-image: none;
239
+ border-color: #007bff; }
240
+ .mo2f_tour_btn-outline-primary:hover {
241
+ color: #fff;
242
+ background-color: #007bff;
243
+ border-color: #007bff; }
244
+ .mo2f_tour_btn-outline-primary:focus, .mo2f_tour_btn-outline-primary.focus {
245
+ box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.5); }
246
+ .mo2f_tour_btn-outline-primary.disabled, .mo2f_tour_btn-outline-primary:disabled {
247
+ color: #007bff;
248
+ background-color: transparent; }
249
+ .mo2f_tour_btn-outline-primary:active, .mo2f_tour_btn-outline-primary.active,
250
+ .show > .mo2f_tour_btn-outline-primary.dropdown-toggle {
251
+ color: #fff;
252
+ background-color: #007bff;
253
+ border-color: #007bff; }
254
+
255
+ .mo2f_tour_btn-outline-secondary {
256
+ color: #868e96;
257
+ background-color: transparent;
258
+ background-image: none;
259
+ border-color: #868e96; }
260
+ .mo2f_tour_btn-outline-secondary:hover {
261
+ color: #fff;
262
+ background-color: #868e96;
263
+ border-color: #868e96; }
264
+ .mo2f_tour_btn-outline-secondary:focus, .mo2f_tour_btn-outline-secondary.focus {
265
+ box-shadow: 0 0 0 3px rgba(134, 142, 150, 0.5); }
266
+ .mo2f_tour_btn-outline-secondary.disabled, .mo2f_tour_btn-outline-secondary:disabled {
267
+ color: #868e96;
268
+ background-color: transparent; }
269
+ .mo2f_tour_btn-outline-secondary:active, .mo2f_tour_btn-outline-secondary.active,
270
+ .show > .mo2f_tour_btn-outline-secondary.dropdown-toggle {
271
+ color: #fff;
272
+ background-color: #868e96;
273
+ border-color: #868e96; }
274
+
275
+ .mo2f_tour_btn-outline-success {
276
+ color: #28a745;
277
+ background-color: transparent;
278
+ background-image: none;
279
+ border-color: #28a745; }
280
+ .mo2f_tour_btn-outline-success:hover {
281
+ color: #fff;
282
+ background-color: #28a745;
283
+ border-color: #28a745; }
284
+ .mo2f_tour_btn-outline-success:focus, .mo2f_tour_btn-outline-success.focus {
285
+ box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.5); }
286
+ .mo2f_tour_btn-outline-success.disabled, .mo2f_tour_btn-outline-success:disabled {
287
+ color: #28a745;
288
+ background-color: transparent; }
289
+ .mo2f_tour_btn-outline-success:active, .mo2f_tour_btn-outline-success.active,
290
+ .show > .mo2f_tour_btn-outline-success.dropdown-toggle {
291
+ color: #fff;
292
+ background-color: #28a745;
293
+ border-color: #28a745; }
294
+
295
+ .mo2f_tour_btn-outline-info {
296
+ color: #17a2b8;
297
+ background-color: transparent;
298
+ background-image: none;
299
+ border-color: #17a2b8; }
300
+ .mo2f_tour_btn-outline-info:hover {
301
+ color: #fff;
302
+ background-color: #17a2b8;
303
+ border-color: #17a2b8; }
304
+ .mo2f_tour_btn-outline-info:focus, .mo2f_tour_btn-outline-info.focus {
305
+ box-shadow: 0 0 0 3px rgba(23, 162, 184, 0.5); }
306
+ .mo2f_tour_btn-outline-info.disabled, .mo2f_tour_btn-outline-info:disabled {
307
+ color: #17a2b8;
308
+ background-color: transparent; }
309
+ .mo2f_tour_btn-outline-info:active, .mo2f_tour_btn-outline-info.active,
310
+ .show > .mo2f_tour_btn-outline-info.dropdown-toggle {
311
+ color: #fff;
312
+ background-color: #17a2b8;
313
+ border-color: #17a2b8; }
314
+
315
+ .mo2f_tour_btn-outline-warning {
316
+ color: #ffc107;
317
+ background-color: transparent;
318
+ background-image: none;
319
+ border-color: #ffc107; }
320
+ .mo2f_tour_btn-outline-warning:hover {
321
+ color: #fff;
322
+ background-color: #ffc107;
323
+ border-color: #ffc107; }
324
+ .mo2f_tour_btn-outline-warning:focus, .mo2f_tour_btn-outline-warning.focus {
325
+ box-shadow: 0 0 0 3px rgba(255, 193, 7, 0.5); }
326
+ .mo2f_tour_btn-outline-warning.disabled, .mo2f_tour_btn-outline-warning:disabled {
327
+ color: #ffc107;
328
+ background-color: transparent; }
329
+ .mo2f_tour_btn-outline-warning:active, .mo2f_tour_btn-outline-warning.active,
330
+ .show > .mo2f_tour_btn-outline-warning.dropdown-toggle {
331
+ color: #fff;
332
+ background-color: #ffc107;
333
+ border-color: #ffc107; }
334
+
335
+ .mo2f_tour_btn-outline-danger {
336
+ color: #dc3545;
337
+ background-color: transparent;
338
+ background-image: none;
339
+ border-color: #dc3545; }
340
+ .mo2f_tour_btn-outline-danger:hover {
341
+ color: #fff;
342
+ background-color: #dc3545;
343
+ border-color: #dc3545; }
344
+ .mo2f_tour_btn-outline-danger:focus, .mo2f_tour_btn-outline-danger.focus {
345
+ box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.5); }
346
+ .mo2f_tour_btn-outline-danger.disabled, .mo2f_tour_btn-outline-danger:disabled {
347
+ color: #dc3545;
348
+ background-color: transparent; }
349
+ .mo2f_tour_btn-outline-danger:active, .mo2f_tour_btn-outline-danger.active,
350
+ .show > .mo2f_tour_btn-outline-danger.dropdown-toggle {
351
+ color: #fff;
352
+ background-color: #dc3545;
353
+ border-color: #dc3545; }
354
+
355
+ .mo2f_tour_btn-outline-light {
356
+ color: #f8f9fa;
357
+ background-color: transparent;
358
+ background-image: none;
359
+ border-color: #f8f9fa; }
360
+ .mo2f_tour_btn-outline-light:hover {
361
+ color: #fff;
362
+ background-color: #f8f9fa;
363
+ border-color: #f8f9fa; }
364
+ .mo2f_tour_btn-outline-light:focus, .mo2f_tour_btn-outline-light.focus {
365
+ box-shadow: 0 0 0 3px rgba(248, 249, 250, 0.5); }
366
+ .mo2f_tour_btn-outline-light.disabled, .mo2f_tour_btn-outline-light:disabled {
367
+ color: #f8f9fa;
368
+ background-color: transparent; }
369
+ .mo2f_tour_btn-outline-light:active, .mo2f_tour_btn-outline-light.active,
370
+ .show > .mo2f_tour_btn-outline-light.dropdown-toggle {
371
+ color: #fff;
372
+ background-color: #f8f9fa;
373
+ border-color: #f8f9fa; }
374
+
375
+ .mo2f_tour_btn-outline-dark {
376
+ color: #343a40;
377
+ background-color: transparent;
378
+ background-image: none;
379
+ border-color: #343a40; }
380
+ .mo2f_tour_btn-outline-dark:hover {
381
+ color: #fff;
382
+ background-color: #343a40;
383
+ border-color: #343a40; }
384
+ .mo2f_tour_btn-outline-dark:focus, .mo2f_tour_btn-outline-dark.focus {
385
+ box-shadow: 0 0 0 3px rgba(52, 58, 64, 0.5); }
386
+ .mo2f_tour_btn-outline-dark.disabled, .mo2f_tour_btn-outline-dark:disabled {
387
+ color: #343a40;
388
+ background-color: transparent; }
389
+ .mo2f_tour_btn-outline-dark:active, .mo2f_tour_btn-outline-dark.active,
390
+ .show > .mo2f_tour_btn-outline-dark.dropdown-toggle {
391
+ color: #fff;
392
+ background-color: #343a40;
393
+ border-color: #343a40; }
394
+
395
+ .mo2f_tour_btn-link {
396
+ font-weight: normal;
397
+ color: #007bff;
398
+ border-radius: 0; }
399
+ .mo2f_tour_btn-link, .mo2f_tour_btn-link:active, .mo2f_tour_btn-link.active, .mo2f_tour_btn-link:disabled {
400
+ background-color: transparent; }
401
+ .mo2f_tour_btn-link, .mo2f_tour_btn-link:focus, .mo2f_tour_btn-link:active {
402
+ border-color: transparent;
403
+ box-shadow: none; }
404
+ .mo2f_tour_btn-link:hover {
405
+ border-color: transparent; }
406
+ .mo2f_tour_btn-link:focus, .mo2f_tour_btn-link:hover {
407
+ color: #0056b3;
408
+ text-decoration: underline;
409
+ background-color: transparent; }
410
+ .mo2f_tour_btn-link:disabled {
411
+ color: #868e96; }
412
+ .mo2f_tour_btn-link:disabled:focus, .mo2f_tour_btn-link:disabled:hover {
413
+ text-decoration: none; }
414
+
415
+ .mo2f_tour_btn-lg, .mo2f_tour_btn-group-lg > .mo2f_tour_btn {
416
+ padding: 0.5rem 1rem;
417
+ font-size: 1.25rem;
418
+ line-height: 1.5;
419
+ border-radius: 0.3rem; }
420
+
421
+ .mo2f_tour_btn-sm, .mo2f_tour_btn-group-sm > .mo2f_tour_btn {
422
+ padding: 0.25rem 0.5rem;
423
+ font-size: 0.875rem;
424
+ line-height: 1.5;
425
+ border-radius: 0.2rem; }
426
+
427
+ .mo2f_tour_btn-block {
428
+ display: block;
429
+ width: 100%; }
430
+
431
+ .mo2f_tour_btn-block + .mo2f_tour_btn-block {
432
+ margin-top: 0.5rem; }
433
+
434
+ input[type="submit"].mo2f_tour_btn-block,
435
+ input[type="reset"].mo2f_tour_btn-block,
436
+ input[type="button"].mo2f_tour_btn-block {
437
+ width: 100%; }
438
+
439
+ .fade {
440
+ opacity: 0;
441
+ transition: opacity 0.15s linear; }
442
+ .fade.show {
443
+ opacity: 1; }
444
+
445
+ .mo2f_collapse {
446
+ display: none; }
447
+ .mo2f_collapse.show {
448
+ display: block; }
449
+
450
+ tr.mo2f_collapse.show {
451
+ display: table-row; }
452
+
453
+ tbody.mo2f_collapse.show {
454
+ display: table-row-group; }
455
+
456
+ .collapsing {
457
+ position: relative;
458
+ height: 0;
459
+ overflow: hidden;
460
+ transition: height 0.35s ease; }
461
+
462
+ .mo2f_tour_btn-group,
463
+ .mo2f_tour_btn-group-vertical {
464
+ position: relative;
465
+ display: inline-flex;
466
+ vertical-align: middle; }
467
+ .mo2f_tour_btn-group > .mo2f_tour_btn,
468
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn {
469
+ position: relative;
470
+ flex: 0 1 auto;
471
+ margin-bottom: 0; }
472
+ .mo2f_tour_btn-group > .mo2f_tour_btn:hover,
473
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn:hover {
474
+ z-index: 2; }
475
+ .mo2f_tour_btn-group > .mo2f_tour_btn:focus, .mo2f_tour_btn-group > .mo2f_tour_btn:active, .mo2f_tour_btn-group > .mo2f_tour_btn.active,
476
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn:focus,
477
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn:active,
478
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn.active {
479
+ z-index: 2; }
480
+ .mo2f_tour_btn-group .mo2f_tour_btn + .mo2f_tour_btn,
481
+ .mo2f_tour_btn-group .mo2f_tour_btn + .mo2f_tour_btn-group,
482
+ .mo2f_tour_btn-group .mo2f_tour_btn-group + .mo2f_tour_btn,
483
+ .mo2f_tour_btn-group .mo2f_tour_btn-group + .mo2f_tour_btn-group,
484
+ .mo2f_tour_btn-group-vertical .mo2f_tour_btn + .mo2f_tour_btn,
485
+ .mo2f_tour_btn-group-vertical .mo2f_tour_btn + .mo2f_tour_btn-group,
486
+ .mo2f_tour_btn-group-vertical .mo2f_tour_btn-group + .mo2f_tour_btn,
487
+ .mo2f_tour_btn-group-vertical .mo2f_tour_btn-group + .mo2f_tour_btn-group {
488
+ margin-left: -1px; }
489
+
490
+ .mo2f_tour_btn-toolbar {
491
+ display: flex;
492
+ flex-wrap: wrap;
493
+ justify-content: flex-start; }
494
+ .mo2f_tour_btn-toolbar .input-group {
495
+ width: auto; }
496
+
497
+ .mo2f_tour_btn-group > .mo2f_tour_btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
498
+ border-radius: 0; }
499
+
500
+ .mo2f_tour_btn-group > .mo2f_tour_btn:first-child {
501
+ margin-left: 0; }
502
+ .mo2f_tour_btn-group > .mo2f_tour_btn:first-child:not(:last-child):not(.dropdown-toggle) {
503
+ border-top-right-radius: 0;
504
+ border-bottom-right-radius: 0; }
505
+
506
+ .mo2f_tour_btn-group > .mo2f_tour_btn:last-child:not(:first-child),
507
+ .mo2f_tour_btn-group > .dropdown-toggle:not(:first-child) {
508
+ border-top-left-radius: 0;
509
+ border-bottom-left-radius: 0; }
510
+
511
+ .mo2f_tour_btn-group > .mo2f_tour_btn-group {
512
+ float: left; }
513
+
514
+ .mo2f_tour_btn-group > .mo2f_tour_btn-group:not(:first-child):not(:last-child) > .mo2f_tour_btn {
515
+ border-radius: 0; }
516
+
517
+ .mo2f_tour_btn-group > .mo2f_tour_btn-group:first-child:not(:last-child) > .mo2f_tour_btn:last-child,
518
+ .mo2f_tour_btn-group > .mo2f_tour_btn-group:first-child:not(:last-child) > .dropdown-toggle {
519
+ border-top-right-radius: 0;
520
+ border-bottom-right-radius: 0; }
521
+
522
+ .mo2f_tour_btn-group > .mo2f_tour_btn-group:last-child:not(:first-child) > .mo2f_tour_btn:first-child {
523
+ border-top-left-radius: 0;
524
+ border-bottom-left-radius: 0; }
525
+
526
+ .mo2f_tour_btn + .dropdown-toggle-split {
527
+ padding-right: 0.5625rem;
528
+ padding-left: 0.5625rem; }
529
+ .mo2f_tour_btn + .dropdown-toggle-split::after {
530
+ margin-left: 0; }
531
+
532
+ .mo2f_tour_btn-sm + .dropdown-toggle-split, .mo2f_tour_btn-group-sm > .mo2f_tour_btn + .dropdown-toggle-split {
533
+ padding-right: 0.375rem;
534
+ padding-left: 0.375rem; }
535
+
536
+ .mo2f_tour_btn-lg + .dropdown-toggle-split, .mo2f_tour_btn-group-lg > .mo2f_tour_btn + .dropdown-toggle-split {
537
+ padding-right: 0.75rem;
538
+ padding-left: 0.75rem; }
539
+
540
+ .mo2f_tour_btn-group-vertical {
541
+ display: inline-flex;
542
+ flex-direction: column;
543
+ align-items: flex-start;
544
+ justify-content: center; }
545
+ .mo2f_tour_btn-group-vertical .mo2f_tour_btn,
546
+ .mo2f_tour_btn-group-vertical .mo2f_tour_btn-group {
547
+ width: 100%; }
548
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn + .mo2f_tour_btn,
549
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn + .mo2f_tour_btn-group,
550
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn-group + .mo2f_tour_btn,
551
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn-group + .mo2f_tour_btn-group {
552
+ margin-top: -1px;
553
+ margin-left: 0; }
554
+
555
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn:not(:first-child):not(:last-child) {
556
+ border-radius: 0; }
557
+
558
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn:first-child:not(:last-child) {
559
+ border-bottom-right-radius: 0;
560
+ border-bottom-left-radius: 0; }
561
+
562
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn:last-child:not(:first-child) {
563
+ border-top-left-radius: 0;
564
+ border-top-right-radius: 0; }
565
+
566
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn-group:not(:first-child):not(:last-child) > .mo2f_tour_btn {
567
+ border-radius: 0; }
568
+
569
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn-group:first-child:not(:last-child) > .mo2f_tour_btn:last-child,
570
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn-group:first-child:not(:last-child) > .dropdown-toggle {
571
+ border-bottom-right-radius: 0;
572
+ border-bottom-left-radius: 0; }
573
+
574
+ .mo2f_tour_btn-group-vertical > .mo2f_tour_btn-group:last-child:not(:first-child) > .mo2f_tour_btn:first-child {
575
+ border-top-left-radius: 0;
576
+ border-top-right-radius: 0; }
577
+
578
+ [data-toggle="buttons"] > .mo2f_tour_btn input[type="radio"],
579
+ [data-toggle="buttons"] > .mo2f_tour_btn input[type="checkbox"],
580
+ [data-toggle="buttons"] > .mo2f_tour_btn-group > .mo2f_tour_btn input[type="radio"],
581
+ [data-toggle="buttons"] > .mo2f_tour_btn-group > .btn input[type="checkbox"] {
582
+ position: absolute;
583
+ clip: rect(0, 0, 0, 0);
584
+ pointer-events: none; }
585
+
586
+ .mo2f_popover {
587
+ position: absolute;
588
+ top: 0;
589
+ left: 0;
590
+ right:0;
591
+ z-index: 1060;
592
+ display: block;
593
+ float:top;
594
+ max-width: 276px;
595
+ padding: 1px;
596
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
597
+ font-style: normal;
598
+ font-weight: normal;
599
+ line-height: 1.5;
600
+ text-align: left;
601
+ text-align: start;
602
+ text-decoration: none;
603
+ text-shadow: none;
604
+ text-transform: none;
605
+ letter-spacing: normal;
606
+ word-break: normal;
607
+ word-spacing: normal;
608
+ white-space: normal;
609
+ line-break: auto;
610
+ font-size: 0.875rem;
611
+ word-wrap: break-word;
612
+ background-color: #fff;
613
+ background-clip: padding-box;
614
+ border: 1px solid rgba(0, 0, 0, 0.2);
615
+ border-radius: 0.3rem; }
616
+ .mo2f_popover .mo2f_arrow {
617
+ position: absolute;
618
+ display: block;
619
+ width: 10px;
620
+ height: 5px;
621
+
622
+ }
623
+ .mo2f_popover .mo2f_arrow::before,
624
+ .mo2f_popover .mo2f_arrow::after {
625
+ position: absolute;
626
+ display: block;
627
+ border-color:transparent;
628
+ border-style: solid; }
629
+ .mo2f_popover .mo2f_arrow::before {
630
+ content: "";
631
+ border-width: 11px;
632
+ }
633
+ .mo2f_popover .mo2f_arrow::after {
634
+ content: "";
635
+ border-width: 11px;
636
+
637
+ }
638
+ .mo2f_popover.bs-mo2f_popover-top, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="top"] {
639
+ margin-bottom: 10px; }
640
+ .mo2f_popover.bs-mo2f_popover-top .mo2f_arrow, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="top"] .mo2f_arrow {
641
+ bottom: 0; }
642
+ .mo2f_popover.bs-mo2f_popover-top .mo2f_arrow::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="top"] .mo2f_arrow::before,
643
+ .mo2f_popover.bs-mo2f_popover-top .mo2f_arrow::after, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="top"] .mo2f_arrow::after {
644
+
645
+ border-bottom-width: 0; }
646
+ .mo2f_popover.bs-mo2f_popover-top .mo2f_arrow::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="top"] .mo2f_arrow::before {
647
+ bottom: -11px;
648
+ margin-left: -6px;
649
+ border-top-color: rgba(0, 0, 0, 0.25); }
650
+ .mo2f_popover.bs-mo2f_popover-top .mo2f_arrow::after, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="top"] .mo2f_arrow::after {
651
+ bottom: -10px;
652
+ margin-left: -6px;
653
+ border-top-color: #fff;
654
+ }
655
+ .mo2f_popover.bs-mo2f_popover-right, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="right"] {
656
+
657
+ margin-left: 10px; }
658
+ .mo2f_popover.bs-mo2f_popover-right .mo2f_arrow, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="right"] .mo2f_arrow {
659
+ left: 0; }
660
+ .mo2f_popover.bs-mo2f_popover-right .mo2f_arrow::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="right"] .mo2f_arrow::before,
661
+ .mo2f_popover.bs-mo2f_popover-right .mo2f_arrow::after, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="right"] .mo2f_arrow::after {
662
+ margin-top: -8px;
663
+ border-left-width: 0;
664
+ }
665
+ .mo2f_popover.bs-mo2f_popover-right .mo2f_arrow::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="right"] .mo2f_arrow::before {
666
+ left: -11px;
667
+ border-right-color: rgba(0, 0, 0, 0.25); }
668
+ .mo2f_popover.bs-mo2f_popover-right .mo2f_arrow::after, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="right"] .mo2f_arrow::after {
669
+ left: -10px;
670
+ border-right-color: #fff;
671
+ }
672
+ .mo2f_popover.bs-mo2f_popover-bottom, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="bottom"] {
673
+ margin-top: 10px; }
674
+ .mo2f_popover.bs-mo2f_popover-bottom .mo2f_arrow, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="bottom"] .mo2f_arrow {
675
+ top: 0; }
676
+ .mo2f_popover.bs-mo2f_popover-bottom .mo2f_arrow::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="bottom"] .mo2f_arrow::before,
677
+ .mo2f_popover.bs-mo2f_popover-bottom .mo2f_arrow::after, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="bottom"] .mo2f_arrow::after {
678
+ margin-left: -7px;
679
+ border-top-width: 0;
680
+
681
+ }
682
+ .mo2f_popover.bs-mo2f_popover-bottom .mo2f_arrow::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="bottom"] .mo2f_arrow::before {
683
+ top: -11px;
684
+ border-bottom-color: rgba(0, 0, 0, 0.25); }
685
+ .mo2f_popover.bs-mo2f_popover-bottom .mo2f_arrow::after, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="bottom"] .mo2f_arrow::after {
686
+ top: -10px;
687
+ border-bottom-color: #fff;
688
+
689
+ }
690
+ .mo2f_popover.bs-mo2f_popover-bottom .mo2f_popover-header::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="bottom"] .mo2f_popover-header::before {
691
+ position: absolute;
692
+ top: 0;
693
+ left: 50%;
694
+ display: block;
695
+ width: 20px;
696
+ margin-left: -10px;
697
+ content: "";
698
+ border-bottom: 1px solid #f7f7f7; }
699
+ .mo2f_popover.bs-mo2f_popover-left, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="left"] {
700
+ margin-right: 10px; }
701
+ .mo2f_popover.bs-mo2f_popover-left .mo2f_arrow, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="left"] .mo2f_arrow {
702
+ right: 0;
703
+
704
+ }
705
+ .mo2f_popover.bs-mo2f_popover-left .mo2f_arrow::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="left"] .mo2f_arrow::before,
706
+ .mo2f_popover.bs-mo2f_popover-left .mo2f_arrow::after, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="left"] .mo2f_arrow::after {
707
+ margin-top: -8px;
708
+ border-right-width: 0;
709
+ }
710
+ .mo2f_popover.bs-mo2f_popover-left .mo2f_arrow::before, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="left"] .mo2f_arrow::before {
711
+ right: -11px;
712
+ border-left-color: rgba(0, 0, 0, 0.25); }
713
+ .mo2f_popover.bs-mo2f_popover-left .mo2f_arrow::after, .mo2f_popover.bs-mo2f_popover-auto[x-placement^="left"] .mo2f_arrow::after {
714
+ right: -10px;
715
+ border-left-color: #fff;
716
+ }
717
+
718
+ .mo2f_popover-header {
719
+ padding: 8px 14px;
720
+ margin-bottom: 0;
721
+ font-size: 1rem;
722
+ color: #FFF;
723
+ background-color: #000;
724
+ border-bottom: 1px solid #ebebeb;
725
+ border-top-left-radius: calc(0.3rem - 1px);
726
+ border-top-right-radius: calc(0.3rem - 1px);
727
+ }
728
+ .mo2f_popover-header:empty {
729
+ display: none; }
730
+
731
+ .mo2f_popover-body {
732
+ padding: 9px 14px;
733
+ color: #212529; }
734
+
735
+ .tour-backdrop {
736
+ background-color: #000;
737
+ filter: alpha(opacity=80);
738
+ opacity: .8;
739
+ position: absolute;
740
+ z-index: 1100; }
741
+
742
+ .mo2f_popover[class*="tour-"] {
743
+ z-index: 1102; }
744
+ .mo2f_popover[class*="tour-"] .mo2f_popover-navigation {
745
+ overflow: hidden;
746
+ padding: 9px 14px; }
747
+ .mo2f_popover[class*="tour-"] .mo2f_popover-navigation *[data-role="end"] {
748
+ float: right; }
749
+ .mo2f_popover[class*="tour-"] .mo2f_popover-navigation *[data-role="prev"],
750
+ .mo2f_popover[class*="tour-"] .mo2f_popover-navigation *[data-role="next"],
751
+ .mo2f_popover[class*="tour-"] .mo2f_popover-navigation *[data-role="end"] {
752
+ cursor: pointer; }
753
+ .mo2f_popover[class*="tour-"] .mo2f_popover-navigation *[data-role="prev"].disabled,
754
+ .mo2f_popover[class*="tour-"] .mo2f_popover-navigation *[data-role="next"].disabled,
755
+ .mo2f_popover[class*="tour-"] .mo2f_popover-navigation *[data-role="end"].disabled {
756
+ cursor: default; }
757
+ .mo2f_popover[class*="tour-"].orphan {
758
+ left: 50%;
759
+ margin-top: 0;
760
+ position: fixed;
761
+ top: 50%;
762
+ transform: translate(-50%, -50%); }
763
+ .mo2f_popover[class*="tour-"].orphan .mo2f_arrow {
764
+ display: none; }
includes/js/bootstrap-tour-standalone.min.js ADDED
@@ -0,0 +1,1760 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* ========================================================================
2
+ * bootstrap-tour - v0.12.0
3
+ * http://bootstraptour.com
4
+ * ========================================================================
5
+ * Copyright 2012-2017 Ulrich Sossou
6
+ *
7
+ * ========================================================================
8
+ * Licensed under the MIT License (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * https://opensource.org/licenses/MIT
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ * ========================================================================
20
+ */
21
+
22
+ function _classCallCheck(t, e) {
23
+ if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
24
+ }
25
+
26
+ function _classCallCheck(t, e) {
27
+ if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
28
+ }
29
+
30
+ function _possibleConstructorReturn(t, e) {
31
+ if (!t) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
32
+ return !e || "object" != typeof e && "function" != typeof e ? t : e
33
+ }
34
+
35
+ function _inherits(t, e) {
36
+ if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function, not " + typeof e);
37
+ t.prototype = Object.create(e && e.prototype, {
38
+ constructor: {
39
+ value: t,
40
+ enumerable: !1,
41
+ writable: !0,
42
+ configurable: !0
43
+ }
44
+ }), e && (Object.setPrototypeOf ? Object.setPrototypeOf(t, e) : t.__proto__ = e)
45
+ }! function(t, e) {
46
+ "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : t.Popper = e()
47
+ }(this, function() {
48
+ "use strict";
49
+
50
+ function t(t) {
51
+ var e = {};
52
+ return t && "[object Function]" === e.toString.call(t)
53
+ }
54
+
55
+ function e(t, e) {
56
+ if (1 !== t.nodeType) return [];
57
+ var n = window.getComputedStyle(t, null);
58
+ return e ? n[e] : n
59
+ }
60
+
61
+ function n(t) {
62
+ return "HTML" === t.nodeName ? t : t.parentNode || t.host
63
+ }
64
+
65
+ function o(t) {
66
+ if (!t || -1 !== ["HTML", "BODY", "#document"].indexOf(t.nodeName)) return window.document.body;
67
+ var i = e(t),
68
+ r = i.overflow,
69
+ s = i.overflowX,
70
+ a = i.overflowY;
71
+ return /(auto|scroll)/.test(r + a + s) ? t : o(n(t))
72
+ }
73
+
74
+ function i(t) {
75
+ var n = t && t.offsetParent,
76
+ o = n && n.nodeName;
77
+ return o && "BODY" !== o && "HTML" !== o ? -1 !== ["TD", "TABLE"].indexOf(n.nodeName) && "static" === e(n, "position") ? i(n) : n : window.document.documentElement
78
+ }
79
+
80
+ function r(t) {
81
+ var e = t.nodeName;
82
+ return "BODY" !== e && ("HTML" === e || i(t.firstElementChild) === t)
83
+ }
84
+
85
+ function s(t) {
86
+ return null !== t.parentNode ? s(t.parentNode) : t
87
+ }
88
+
89
+ function a(t, e) {
90
+ if (!(t && t.nodeType && e && e.nodeType)) return window.document.documentElement;
91
+ var n = t.compareDocumentPosition(e) & Node.DOCUMENT_POSITION_FOLLOWING,
92
+ o = n ? t : e,
93
+ p = n ? e : t,
94
+ u = document.createRange();
95
+ u.setStart(o, 0), u.setEnd(p, 0);
96
+ var l = u.commonAncestorContainer;
97
+ if (t !== l && e !== l || o.contains(p)) return r(l) ? l : i(l);
98
+ var c = s(t);
99
+ return c.host ? a(c.host, e) : a(t, s(e).host)
100
+ }
101
+
102
+ function p(t) {
103
+ var e = "top" === (arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : "top") ? "scrollTop" : "scrollLeft",
104
+ n = t.nodeName;
105
+ if ("BODY" === n || "HTML" === n) {
106
+ var o = window.document.documentElement;
107
+ return (window.document.scrollingElement || o)[e]
108
+ }
109
+ return t[e]
110
+ }
111
+
112
+ function u(t, e) {
113
+ var n = arguments.length > 2 && void 0 !== arguments[2] && arguments[2],
114
+ o = p(e, "top"),
115
+ i = p(e, "left"),
116
+ r = n ? -1 : 1;
117
+ return t.top += o * r, t.bottom += o * r, t.left += i * r, t.right += i * r, t
118
+ }
119
+
120
+ function l(t, e) {
121
+ var n = "x" === e ? "Left" : "Top",
122
+ o = "Left" === n ? "Right" : "Bottom";
123
+ return +t["border" + n + "Width"].split("px")[0] + +t["border" + o + "Width"].split("px")[0]
124
+ }
125
+
126
+ function c(t, e, n, o) {
127
+ return Math.max(e["offset" + t], e["scroll" + t], n["client" + t], n["offset" + t], n["scroll" + t], Z() ? n["offset" + t] + o["margin" + ("Height" === t ? "Top" : "Left")] + o["margin" + ("Height" === t ? "Bottom" : "Right")] : 0)
128
+ }
129
+
130
+ function h() {
131
+ var t = window.document.body,
132
+ e = window.document.documentElement,
133
+ n = Z() && window.getComputedStyle(e);
134
+ return {
135
+ height: c("Height", t, e, n),
136
+ width: c("Width", t, e, n)
137
+ }
138
+ }
139
+
140
+ function f(t) {
141
+ return nt({}, t, {
142
+ right: t.left + t.width,
143
+ bottom: t.top + t.height
144
+ })
145
+ }
146
+
147
+ function d(t) {
148
+ var n = {};
149
+ if (Z()) try {
150
+ n = t.getBoundingClientRect();
151
+ var o = p(t, "top"),
152
+ i = p(t, "left");
153
+ n.top += o, n.left += i, n.bottom += o, n.right += i
154
+ } catch (t) {} else n = t.getBoundingClientRect();
155
+ var r = {
156
+ left: n.left,
157
+ top: n.top,
158
+ width: n.right - n.left,
159
+ height: n.bottom - n.top
160
+ },
161
+ s = "HTML" === t.nodeName ? h() : {},
162
+ a = s.width || t.clientWidth || r.right - r.left,
163
+ u = s.height || t.clientHeight || r.bottom - r.top,
164
+ c = t.offsetWidth - a,
165
+ d = t.offsetHeight - u;
166
+ if (c || d) {
167
+ var m = e(t);
168
+ c -= l(m, "x"), d -= l(m, "y"), r.width -= c, r.height -= d
169
+ }
170
+ return f(r)
171
+ }
172
+
173
+ function m(t, n) {
174
+ var i = Z(),
175
+ r = "HTML" === n.nodeName,
176
+ s = d(t),
177
+ a = d(n),
178
+ p = o(t),
179
+ l = e(n),
180
+ c = +l.borderTopWidth.split("px")[0],
181
+ h = +l.borderLeftWidth.split("px")[0],
182
+ m = f({
183
+ top: s.top - a.top - c,
184
+ left: s.left - a.left - h,
185
+ width: s.width,
186
+ height: s.height
187
+ });
188
+ if (m.marginTop = 0, m.marginLeft = 0, !i && r) {
189
+ var g = +l.marginTop.split("px")[0],
190
+ v = +l.marginLeft.split("px")[0];
191
+ m.top -= c - g, m.bottom -= c - g, m.left -= h - v, m.right -= h - v, m.marginTop = g, m.marginLeft = v
192
+ }
193
+ return (i ? n.contains(p) : n === p && "BODY" !== p.nodeName) && (m = u(m, n)), m
194
+ }
195
+
196
+ function g(t) {
197
+ var e = window.document.documentElement,
198
+ n = m(t, e),
199
+ o = Math.max(e.clientWidth, window.innerWidth || 0),
200
+ i = Math.max(e.clientHeight, window.innerHeight || 0),
201
+ r = p(e),
202
+ s = p(e, "left");
203
+ return f({
204
+ top: r - n.top + n.marginTop,
205
+ left: s - n.left + n.marginLeft,
206
+ width: o,
207
+ height: i
208
+ })
209
+ }
210
+
211
+ function v(t) {
212
+ var o = t.nodeName;
213
+ return "BODY" !== o && "HTML" !== o && ("fixed" === e(t, "position") || v(n(t)))
214
+ }
215
+
216
+ function _(t, e, i, r) {
217
+ var s = {
218
+ top: 0,
219
+ left: 0
220
+ },
221
+ p = a(t, e);
222
+ if ("viewport" === r) s = g(p);
223
+ else {
224
+ var u = void 0;
225
+ "scrollParent" === r ? "BODY" === (u = o(n(t))).nodeName && (u = window.document.documentElement) : u = "window" === r ? window.document.documentElement : r;
226
+ var l = m(u, p);
227
+ if ("HTML" !== u.nodeName || v(p)) s = l;
228
+ else {
229
+ var c = h(),
230
+ f = c.height,
231
+ d = c.width;
232
+ s.top += l.top - l.marginTop, s.bottom = f + l.top, s.left += l.left - l.marginLeft, s.right = d + l.left
233
+ }
234
+ }
235
+ return s.left += i, s.top += i, s.right -= i, s.bottom -= i, s
236
+ }
237
+
238
+ function b(t) {
239
+ return t.width * t.height
240
+ }
241
+
242
+ function y(t, e, n, o, i) {
243
+ var r = arguments.length > 5 && void 0 !== arguments[5] ? arguments[5] : 0;
244
+ if (-1 === t.indexOf("auto")) return t;
245
+ var s = _(n, o, r, i),
246
+ a = {
247
+ top: {
248
+ width: s.width,
249
+ height: e.top - s.top
250
+ },
251
+ right: {
252
+ width: s.right - e.right,
253
+ height: s.height
254
+ },
255
+ bottom: {
256
+ width: s.width,
257
+ height: s.bottom - e.bottom
258
+ },
259
+ left: {
260
+ width: e.left - s.left,
261
+ height: s.height
262
+ }
263
+ },
264
+ p = Object.keys(a).map(function(t) {
265
+ return nt({
266
+ key: t
267
+ }, a[t], {
268
+ area: b(a[t])
269
+ })
270
+ }).sort(function(t, e) {
271
+ return e.area - t.area
272
+ }),
273
+ u = p.filter(function(t) {
274
+ var e = t.width,
275
+ o = t.height;
276
+ return e >= n.clientWidth && o >= n.clientHeight
277
+ }),
278
+ l = u.length > 0 ? u[0].key : p[0].key,
279
+ c = t.split("-")[1];
280
+ return l + (c ? "-" + c : "")
281
+ }
282
+
283
+ function w(t, e, n) {
284
+ return m(n, a(e, n))
285
+ }
286
+
287
+ function E(t) {
288
+ var e = window.getComputedStyle(t),
289
+ n = parseFloat(e.marginTop) + parseFloat(e.marginBottom),
290
+ o = parseFloat(e.marginLeft) + parseFloat(e.marginRight);
291
+ return {
292
+ width: t.offsetWidth + o,
293
+ height: t.offsetHeight + n
294
+ }
295
+ }
296
+
297
+ function S(t) {
298
+ var e = {
299
+ left: "right",
300
+ right: "left",
301
+ bottom: "top",
302
+ top: "bottom"
303
+ };
304
+ return t.replace(/left|right|bottom|top/g, function(t) {
305
+ return e[t]
306
+ })
307
+ }
308
+
309
+ function T(t, e, n) {
310
+ n = n.split("-")[0];
311
+ var o = E(t),
312
+ i = {
313
+ width: o.width,
314
+ height: o.height
315
+ },
316
+ r = -1 !== ["right", "left"].indexOf(n),
317
+ s = r ? "top" : "left",
318
+ a = r ? "left" : "top",
319
+ p = r ? "height" : "width",
320
+ u = r ? "width" : "height";
321
+ return i[s] = e[s] + e[p] / 2 - o[p] / 2, i[a] = n === a ? e[a] - o[u] : e[S(a)], i
322
+ }
323
+
324
+ function O(t, e) {
325
+ return Array.prototype.find ? t.find(e) : t.filter(e)[0]
326
+ }
327
+
328
+ function C(t, e, n) {
329
+ if (Array.prototype.findIndex) return t.findIndex(function(t) {
330
+ return t[e] === n
331
+ });
332
+ var o = O(t, function(t) {
333
+ return t[e] === n
334
+ });
335
+ return t.indexOf(o)
336
+ }
337
+
338
+ function x(e, n, o) {
339
+ return (void 0 === o ? e : e.slice(0, C(e, "name", o))).forEach(function(e) {
340
+ e.function && console.warn("`modifier.function` is deprecated, use `modifier.fn`!");
341
+ var o = e.function || e.fn;
342
+ e.enabled && t(o) && (n.offsets.popper = f(n.offsets.popper), n.offsets.reference = f(n.offsets.reference), n = o(n, e))
343
+ }), n
344
+ }
345
+
346
+ function k() {
347
+ if (!this.state.isDestroyed) {
348
+ var t = {
349
+ instance: this,
350
+ styles: {},
351
+ mo2f_arrowStyles: {},
352
+ attributes: {},
353
+ flipped: !1,
354
+ offsets: {}
355
+ };
356
+ t.offsets.reference = w(this.state, this.popper, this.reference), t.placement = y(this.options.placement, t.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding), t.originalPlacement = t.placement, t.offsets.popper = T(this.popper, t.offsets.reference, t.placement), t.offsets.popper.position = "absolute", t = x(this.modifiers, t), this.state.isCreated ? this.options.onUpdate(t) : (this.state.isCreated = !0, this.options.onCreate(t))
357
+ }
358
+ }
359
+
360
+ function P(t, e) {
361
+ return t.some(function(t) {
362
+ var n = t.name;
363
+ return t.enabled && n === e
364
+ })
365
+ }
366
+
367
+ function D(t) {
368
+ for (var e = [!1, "ms", "Webkit", "Moz", "O"], n = t.charAt(0).toUpperCase() + t.slice(1), o = 0; o < e.length - 1; o++) {
369
+ var i = e[o],
370
+ r = i ? "" + i + n : t;
371
+ if (void 0 !== window.document.body.style[r]) return r
372
+ }
373
+ return null
374
+ }
375
+
376
+ function N() {
377
+ return this.state.isDestroyed = !0, P(this.modifiers, "applyStyle") && (this.popper.removeAttribute("x-placement"), this.popper.style.left = "", this.popper.style.position = "", this.popper.style.top = "", this.popper.style[D("transform")] = ""), this.disableEventListeners(), this.options.removeOnDestroy && this.popper.parentNode.removeChild(this.popper), this
378
+ }
379
+
380
+ function A(t, e, n, i) {
381
+ var r = "BODY" === t.nodeName,
382
+ s = r ? window : t;
383
+ s.addEventListener(e, n, {
384
+ passive: !0
385
+ }), r || A(o(s.parentNode), e, n, i), i.push(s)
386
+ }
387
+
388
+ function H(t, e, n, i) {
389
+ n.updateBound = i, window.addEventListener("resize", n.updateBound, {
390
+ passive: !0
391
+ });
392
+ var r = o(t);
393
+ return A(r, "scroll", n.updateBound, n.scrollParents), n.scrollElement = r, n.eventsEnabled = !0, n
394
+ }
395
+
396
+ function j() {
397
+ this.state.eventsEnabled || (this.state = H(this.reference, this.options, this.state, this.scheduleUpdate))
398
+ }
399
+
400
+ function I(t, e) {
401
+ return window.removeEventListener("resize", e.updateBound), e.scrollParents.forEach(function(t) {
402
+ t.removeEventListener("scroll", e.updateBound)
403
+ }), e.updateBound = null, e.scrollParents = [], e.scrollElement = null, e.eventsEnabled = !1, e
404
+ }
405
+
406
+ function R() {
407
+ this.state.eventsEnabled && (window.cancelAnimationFrame(this.scheduleUpdate), this.state = I(this.reference, this.state))
408
+ }
409
+
410
+ function L(t) {
411
+ return "" !== t && !isNaN(parseFloat(t)) && isFinite(t)
412
+ }
413
+
414
+ function W(t, e) {
415
+ Object.keys(e).forEach(function(n) {
416
+ var o = ""; - 1 !== ["width", "height", "top", "right", "bottom", "left"].indexOf(n) && L(e[n]) && (o = "px"), t.style[n] = e[n] + o
417
+ })
418
+ }
419
+
420
+ function U(t, e) {
421
+ Object.keys(e).forEach(function(n) {
422
+ !1 !== e[n] ? t.setAttribute(n, e[n]) : t.removeAttribute(n)
423
+ })
424
+ }
425
+
426
+ function M(t, e, n) {
427
+ var o = O(t, function(t) {
428
+ return t.name === e
429
+ }),
430
+ i = !!o && t.some(function(t) {
431
+ return t.name === n && t.enabled && t.order < o.order
432
+ });
433
+ if (!i) {
434
+ var r = "`" + e + "`",
435
+ s = "`" + n + "`";
436
+ console.warn(s + " modifier is required by " + r + " modifier in order to work, be sure to include it before " + r + "!")
437
+ }
438
+ return i
439
+ }
440
+
441
+ function F(t) {
442
+ return "end" === t ? "start" : "start" === t ? "end" : t
443
+ }
444
+
445
+ function B(t) {
446
+ var e = arguments.length > 1 && void 0 !== arguments[1] && arguments[1],
447
+ n = it.indexOf(t),
448
+ o = it.slice(n + 1).concat(it.slice(0, n));
449
+ return e ? o.reverse() : o
450
+ }
451
+
452
+ function K(t, e, n, o) {
453
+ var i = t.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),
454
+ r = +i[1],
455
+ s = i[2];
456
+ if (!r) return t;
457
+ if (0 === s.indexOf("%")) {
458
+ var a = void 0;
459
+ switch (s) {
460
+ case "%p":
461
+ a = n;
462
+ break;
463
+ case "%":
464
+ case "%r":
465
+ default:
466
+ a = o
467
+ }
468
+ return f(a)[e] / 100 * r
469
+ }
470
+ if ("vh" === s || "vw" === s) {
471
+ return ("vh" === s ? Math.max(document.documentElement.clientHeight, window.innerHeight || 0) : Math.max(document.documentElement.clientWidth, window.innerWidth || 0)) / 100 * r
472
+ }
473
+ return r
474
+ }
475
+
476
+ function q(t, e, n, o) {
477
+ var i = [0, 0],
478
+ r = -1 !== ["right", "left"].indexOf(o),
479
+ s = t.split(/(\+|\-)/).map(function(t) {
480
+ return t.trim()
481
+ }),
482
+ a = s.indexOf(O(s, function(t) {
483
+ return -1 !== t.search(/,|\s/)
484
+ }));
485
+ s[a] && -1 === s[a].indexOf(",") && console.warn("Offsets separated by white space(s) are deprecated, use a comma (,) instead.");
486
+ var p = /\s*,\s*|\s+/,
487
+ u = -1 !== a ? [s.slice(0, a).concat([s[a].split(p)[0]]), [s[a].split(p)[1]].concat(s.slice(a + 1))] : [s];
488
+ return (u = u.map(function(t, o) {
489
+ var i = (1 === o ? !r : r) ? "height" : "width",
490
+ s = !1;
491
+ return t.reduce(function(t, e) {
492
+ return "" === t[t.length - 1] && -1 !== ["+", "-"].indexOf(e) ? (t[t.length - 1] = e, s = !0, t) : s ? (t[t.length - 1] += e, s = !1, t) : t.concat(e)
493
+ }, []).map(function(t) {
494
+ return K(t, i, e, n)
495
+ })
496
+ })).forEach(function(t, e) {
497
+ t.forEach(function(n, o) {
498
+ L(n) && (i[e] += n * ("-" === t[o - 1] ? -1 : 1))
499
+ })
500
+ }), i
501
+ }
502
+ for (var Y = ["native code", "[object MutationObserverConstructor]"], V = "undefined" != typeof window, Q = ["Edge", "Trident", "Firefox"], G = 0, z = 0; z < Q.length; z += 1)
503
+ if (V && navigator.userAgent.indexOf(Q[z]) >= 0) {
504
+ G = 1;
505
+ break
506
+ } var J = V && function(t) {
507
+ return Y.some(function(e) {
508
+ return (t || "").toString().indexOf(e) > -1
509
+ })
510
+ }(window.MutationObserver) ? function(t) {
511
+ var e = !1,
512
+ n = 0,
513
+ o = document.createElement("span");
514
+ return new MutationObserver(function() {
515
+ t(), e = !1
516
+ }).observe(o, {
517
+ attributes: !0
518
+ }),
519
+ function() {
520
+ e || (e = !0, o.setAttribute("x-index", n), n += 1)
521
+ }
522
+ } : function(t) {
523
+ var e = !1;
524
+ return function() {
525
+ e || (e = !0, setTimeout(function() {
526
+ e = !1, t()
527
+ }, G))
528
+ }
529
+ },
530
+ X = void 0,
531
+ Z = function() {
532
+ return void 0 === X && (X = -1 !== navigator.appVersion.indexOf("MSIE 10")), X
533
+ },
534
+ $ = function(t, e) {
535
+ if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
536
+ },
537
+ tt = function() {
538
+ function t(t, e) {
539
+ for (var n = 0; n < e.length; n++) {
540
+ var o = e[n];
541
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(t, o.key, o)
542
+ }
543
+ }
544
+ return function(e, n, o) {
545
+ return n && t(e.prototype, n), o && t(e, o), e
546
+ }
547
+ }(),
548
+ et = function(t, e, n) {
549
+ return e in t ? Object.defineProperty(t, e, {
550
+ value: n,
551
+ enumerable: !0,
552
+ configurable: !0,
553
+ writable: !0
554
+ }) : t[e] = n, t
555
+ },
556
+ nt = Object.assign || function(t) {
557
+ for (var e = 1; e < arguments.length; e++) {
558
+ var n = arguments[e];
559
+ for (var o in n) Object.prototype.hasOwnProperty.call(n, o) && (t[o] = n[o])
560
+ }
561
+ return t
562
+ },
563
+ ot = ["auto-start", "auto", "auto-end", "top-start", "top", "top-end", "right-start", "right", "right-end", "bottom-end", "bottom", "bottom-start", "left-end", "left", "left-start"],
564
+ it = ot.slice(3),
565
+ rt = {
566
+ FLIP: "flip",
567
+ CLOCKWISE: "clockwise",
568
+ COUNTERCLOCKWISE: "counterclockwise"
569
+ },
570
+ st = {
571
+ placement: "bottom",
572
+ eventsEnabled: !0,
573
+ removeOnDestroy: !1,
574
+ onCreate: function() {},
575
+ onUpdate: function() {},
576
+ modifiers: {
577
+ shift: {
578
+ order: 100,
579
+ enabled: !0,
580
+ fn: function(t) {
581
+ var e = t.placement,
582
+ n = e.split("-")[0],
583
+ o = e.split("-")[1];
584
+ if (o) {
585
+ var i = t.offsets,
586
+ r = i.reference,
587
+ s = i.popper,
588
+ a = -1 !== ["bottom", "top"].indexOf(n),
589
+ p = a ? "left" : "top",
590
+ u = a ? "width" : "height",
591
+ l = {
592
+ start: et({}, p, r[p]),
593
+ end: et({}, p, r[p] + r[u] - s[u])
594
+ };
595
+ t.offsets.popper = nt({}, s, l[o])
596
+ }
597
+ return t
598
+ }
599
+ },
600
+ offset: {
601
+ order: 200,
602
+ enabled: !0,
603
+ fn: function(t, e) {
604
+ var n = e.offset,
605
+ o = t.placement,
606
+ i = t.offsets,
607
+ r = i.popper,
608
+ s = i.reference,
609
+ a = o.split("-")[0],
610
+ p = void 0;
611
+ return p = L(+n) ? [+n, 0] : q(n, r, s, a), "left" === a ? (r.top += p[0], r.left -= p[1]) : "right" === a ? (r.top += p[0], r.left += p[1]) : "top" === a ? (r.left += p[0], r.top -= p[1]) : "bottom" === a && (r.left += p[0], r.top += p[1]), t.popper = r, t
612
+ },
613
+ offset: 0
614
+ },
615
+ preventOverflow: {
616
+ order: 300,
617
+ enabled: !0,
618
+ fn: function(t, e) {
619
+ var n = e.boundariesElement || i(t.instance.popper);
620
+ t.instance.reference === n && (n = i(n));
621
+ var o = _(t.instance.popper, t.instance.reference, e.padding, n);
622
+ e.boundaries = o;
623
+ var r = e.priority,
624
+ s = t.offsets.popper,
625
+ a = {
626
+ primary: function(t) {
627
+ var n = s[t];
628
+ return s[t] < o[t] && !e.escapeWithReference && (n = Math.max(s[t], o[t])), et({}, t, n)
629
+ },
630
+ secondary: function(t) {
631
+ var n = "right" === t ? "left" : "top",
632
+ i = s[n];
633
+ return s[t] > o[t] && !e.escapeWithReference && (i = Math.min(s[n], o[t] - ("right" === t ? s.width : s.height))), et({}, n, i)
634
+ }
635
+ };
636
+ return r.forEach(function(t) {
637
+ var e = -1 !== ["left", "top"].indexOf(t) ? "primary" : "secondary";
638
+ s = nt({}, s, a[e](t))
639
+ }), t.offsets.popper = s, t
640
+ },
641
+ priority: ["left", "right", "top", "bottom"],
642
+ padding: 5,
643
+ boundariesElement: "scrollParent"
644
+ },
645
+ keepTogether: {
646
+ order: 400,
647
+ enabled: !0,
648
+ fn: function(t) {
649
+ var e = t.offsets,
650
+ n = e.popper,
651
+ o = e.reference,
652
+ i = t.placement.split("-")[0],
653
+ r = Math.floor,
654
+ s = -1 !== ["top", "bottom"].indexOf(i),
655
+ a = s ? "right" : "bottom",
656
+ p = s ? "left" : "top",
657
+ u = s ? "width" : "height";
658
+ return n[a] < r(o[p]) && (t.offsets.popper[p] = r(o[p]) - n[u]), n[p] > r(o[a]) && (t.offsets.popper[p] = r(o[a])), t
659
+ }
660
+ },
661
+ mo2f_arrow: {
662
+ order: 500,
663
+ enabled: !0,
664
+ fn: function(t, n) {
665
+ if (!M(t.instance.modifiers, "mo2f_arrow", "keepTogether")) return t;
666
+ var o = n.element;
667
+ if ("string" == typeof o) {
668
+ if (!(o = t.instance.popper.querySelector(o))) return t
669
+ } else if (!t.instance.popper.contains(o)) return console.warn("WARNING: `mo2f_arrow.element` must be child of its popper element!"), t;
670
+ var i = t.placement.split("-")[0],
671
+ r = t.offsets,
672
+ s = r.popper,
673
+ a = r.reference,
674
+ p = -1 !== ["left", "right"].indexOf(i),
675
+ u = p ? "height" : "width",
676
+ l = p ? "Top" : "Left",
677
+ c = l.toLowerCase(),
678
+ h = p ? "left" : "top",
679
+ d = p ? "bottom" : "right",
680
+ m = E(o)[u];
681
+ a[d] - m < s[c] && (t.offsets.popper[c] -= s[c] - (a[d] - m)), a[c] + m > s[d] && (t.offsets.popper[c] += a[c] + m - s[d]);
682
+ var g = a[c] + a[u] / 2 - m / 2,
683
+ v = e(t.instance.popper, "margin" + l).replace("px", ""),
684
+ _ = g - f(t.offsets.popper)[c] - v;
685
+ return _ = Math.max(Math.min(s[u] - m, _), 0), t.mo2f_arrowElement = o, t.offsets.mo2f_arrow = {}, t.offsets.mo2f_arrow[c] = Math.round(_), t.offsets.mo2f_arrow[h] = "", t
686
+ },
687
+ element: "[x-mo2f_arrow]"
688
+ },
689
+ flip: {
690
+ order: 600,
691
+ enabled: !0,
692
+ fn: function(t, e) {
693
+ if (P(t.instance.modifiers, "inner")) return t;
694
+ if (t.flipped && t.placement === t.originalPlacement) return t;
695
+ var n = _(t.instance.popper, t.instance.reference, e.padding, e.boundariesElement),
696
+ o = t.placement.split("-")[0],
697
+ i = S(o),
698
+ r = t.placement.split("-")[1] || "",
699
+ s = [];
700
+ switch (e.behavior) {
701
+ case rt.FLIP:
702
+ s = [o, i];
703
+ break;
704
+ case rt.CLOCKWISE:
705
+ s = B(o);
706
+ break;
707
+ case rt.COUNTERCLOCKWISE:
708
+ s = B(o, !0);
709
+ break;
710
+ default:
711
+ s = e.behavior
712
+ }
713
+ return s.forEach(function(a, p) {
714
+ if (o !== a || s.length === p + 1) return t;
715
+ o = t.placement.split("-")[0], i = S(o);
716
+ var u = t.offsets.popper,
717
+ l = t.offsets.reference,
718
+ c = Math.floor,
719
+ h = "left" === o && c(u.right) > c(l.left) || "right" === o && c(u.left) < c(l.right) || "top" === o && c(u.bottom) > c(l.top) || "bottom" === o && c(u.top) < c(l.bottom),
720
+ f = c(u.left) < c(n.left),
721
+ d = c(u.right) > c(n.right),
722
+ m = c(u.top) < c(n.top),
723
+ g = c(u.bottom) > c(n.bottom),
724
+ v = "left" === o && f || "right" === o && d || "top" === o && m || "bottom" === o && g,
725
+ _ = -1 !== ["top", "bottom"].indexOf(o),
726
+ b = !!e.flipVariations && (_ && "start" === r && f || _ && "end" === r && d || !_ && "start" === r && m || !_ && "end" === r && g);
727
+ (h || v || b) && (t.flipped = !0, (h || v) && (o = s[p + 1]), b && (r = F(r)), t.placement = o + (r ? "-" + r : ""), t.offsets.popper = nt({}, t.offsets.popper, T(t.instance.popper, t.offsets.reference, t.placement)), t = x(t.instance.modifiers, t, "flip"))
728
+ }), t
729
+ },
730
+ behavior: "flip",
731
+ padding: 5,
732
+ boundariesElement: "viewport"
733
+ },
734
+ inner: {
735
+ order: 700,
736
+ enabled: !1,
737
+ fn: function(t) {
738
+ var e = t.placement,
739
+ n = e.split("-")[0],
740
+ o = t.offsets,
741
+ i = o.popper,
742
+ r = o.reference,
743
+ s = -1 !== ["left", "right"].indexOf(n),
744
+ a = -1 === ["top", "left"].indexOf(n);
745
+ return i[s ? "left" : "top"] = r[n] - (a ? i[s ? "width" : "height"] : 0), t.placement = S(e), t.offsets.popper = f(i), t
746
+ }
747
+ },
748
+ hide: {
749
+ order: 800,
750
+ enabled: !0,
751
+ fn: function(t) {
752
+ if (!M(t.instance.modifiers, "hide", "preventOverflow")) return t;
753
+ var e = t.offsets.reference,
754
+ n = O(t.instance.modifiers, function(t) {
755
+ return "preventOverflow" === t.name
756
+ }).boundaries;
757
+ if (e.bottom < n.top || e.left > n.right || e.top > n.bottom || e.right < n.left) {
758
+ if (!0 === t.hide) return t;
759
+ t.hide = !0, t.attributes["x-out-of-boundaries"] = ""
760
+ } else {
761
+ if (!1 === t.hide) return t;
762
+ t.hide = !1, t.attributes["x-out-of-boundaries"] = !1
763
+ }
764
+ return t
765
+ }
766
+ },
767
+ computeStyle: {
768
+ order: 850,
769
+ enabled: !0,
770
+ fn: function(t, e) {
771
+ var n = e.x,
772
+ o = e.y,
773
+ r = t.offsets.popper,
774
+ s = O(t.instance.modifiers, function(t) {
775
+ return "applyStyle" === t.name
776
+ }).gpuAcceleration;
777
+ void 0 !== s && console.warn("WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!");
778
+ var a = void 0 !== s ? s : e.gpuAcceleration,
779
+ p = d(i(t.instance.popper)),
780
+ u = {
781
+ position: r.position
782
+ },
783
+ l = {
784
+ left: Math.floor(r.left),
785
+ top: Math.floor(r.top),
786
+ bottom: Math.floor(r.bottom),
787
+ right: Math.floor(r.right)
788
+ },
789
+ c = "bottom" === n ? "top" : "bottom",
790
+ h = "right" === o ? "left" : "right",
791
+ f = D("transform"),
792
+ m = void 0,
793
+ g = void 0;
794
+ if (g = "bottom" === c ? -p.height + l.bottom : l.top, m = "right" === h ? -p.width + l.right : l.left, a && f) u[f] = "translate3d(" + m + "px, " + g + "px, 0)", u[c] = 0, u[h] = 0, u.willChange = "transform";
795
+ else {
796
+ var v = "bottom" === c ? -1 : 1,
797
+ _ = "right" === h ? -1 : 1;
798
+ u[c] = g * v, u[h] = m * _, u.willChange = c + ", " + h
799
+ }
800
+ var b = {
801
+ "x-placement": t.placement
802
+ };
803
+ return t.attributes = nt({}, b, t.attributes), t.styles = nt({}, u, t.styles), t.mo2f_arrowStyles = nt({}, t.offsets.mo2f_arrow, t.mo2f_arrowStyles), t
804
+ },
805
+ gpuAcceleration: !0,
806
+ x: "bottom",
807
+ y: "right"
808
+ },
809
+ applyStyle: {
810
+ order: 900,
811
+ enabled: !0,
812
+ fn: function(t) {
813
+ return W(t.instance.popper, t.styles), U(t.instance.popper, t.attributes), t.mo2f_arrowElement && Object.keys(t.mo2f_arrowStyles).length && W(t.mo2f_arrowElement, t.mo2f_arrowStyles), t
814
+ },
815
+ onLoad: function(t, e, n, o, i) {
816
+ var r = w(i, e, t),
817
+ s = y(n.placement, r, e, t, n.modifiers.flip.boundariesElement, n.modifiers.flip.padding);
818
+ return e.setAttribute("x-placement", s), W(e, {
819
+ position: "absolute"
820
+ }), n
821
+ },
822
+ gpuAcceleration: void 0
823
+ }
824
+ }
825
+ },
826
+ at = function() {
827
+ function e(n, o) {
828
+ var i = this,
829
+ r = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {};
830
+ $(this, e), this.scheduleUpdate = function() {
831
+ return requestAnimationFrame(i.update)
832
+ }, this.update = J(this.update.bind(this)), this.options = nt({}, e.Defaults, r), this.state = {
833
+ isDestroyed: !1,
834
+ isCreated: !1,
835
+ scrollParents: []
836
+ }, this.reference = n.jquery ? n[0] : n, this.popper = o.jquery ? o[0] : o, this.options.modifiers = {}, Object.keys(nt({}, e.Defaults.modifiers, r.modifiers)).forEach(function(t) {
837
+ i.options.modifiers[t] = nt({}, e.Defaults.modifiers[t] || {}, r.modifiers ? r.modifiers[t] : {})
838
+ }), this.modifiers = Object.keys(this.options.modifiers).map(function(t) {
839
+ return nt({
840
+ name: t
841
+ }, i.options.modifiers[t])
842
+ }).sort(function(t, e) {
843
+ return t.order - e.order
844
+ }), this.modifiers.forEach(function(e) {
845
+ e.enabled && t(e.onLoad) && e.onLoad(i.reference, i.popper, i.options, e, i.state)
846
+ }), this.update();
847
+ var s = this.options.eventsEnabled;
848
+ s && this.enableEventListeners(), this.state.eventsEnabled = s
849
+ }
850
+ return tt(e, [{
851
+ key: "update",
852
+ value: function() {
853
+ return k.call(this)
854
+ }
855
+ }, {
856
+ key: "destroy",
857
+ value: function() {
858
+ return N.call(this)
859
+ }
860
+ }, {
861
+ key: "enableEventListeners",
862
+ value: function() {
863
+ return j.call(this)
864
+ }
865
+ }, {
866
+ key: "disableEventListeners",
867
+ value: function() {
868
+ return R.call(this)
869
+ }
870
+ }]), e
871
+ }();
872
+ return at.Utils = ("undefined" != typeof window ? window : global).PopperUtils, at.placements = ot, at.Defaults = st, at
873
+ });
874
+ var Util = function(t) {
875
+ function e(t) {
876
+ return {}.toString.call(t).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
877
+ }
878
+
879
+ function n(t) {
880
+ return (t[0] || t).nodeType
881
+ }
882
+
883
+ function o() {
884
+ return {
885
+ bindType: s.end,
886
+ delegateType: s.end,
887
+ handle: function(e) {
888
+ if (t(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
889
+ }
890
+ }
891
+ }
892
+
893
+ function i() {
894
+ if (window.QUnit) return !1;
895
+ var t = document.createElement("bootstrap");
896
+ for (var e in a)
897
+ if (void 0 !== t.style[e]) return {
898
+ end: a[e]
899
+ };
900
+ return !1
901
+ }
902
+
903
+ function r(e) {
904
+ var n = this,
905
+ o = !1;
906
+ return t(this).one(p.TRANSITION_END, function() {
907
+ o = !0
908
+ }), setTimeout(function() {
909
+ o || p.triggerTransitionEnd(n)
910
+ }, e), this
911
+ }
912
+ var s = !1,
913
+ a = {
914
+ WebkitTransition: "webkitTransitionEnd",
915
+ MozTransition: "transitionend",
916
+ OTransition: "oTransitionEnd otransitionend",
917
+ transition: "transitionend"
918
+ },
919
+ p = {
920
+ TRANSITION_END: "bsTransitionEnd",
921
+ getUID: function(t) {
922
+ do {
923
+ t += ~~(1e6 * Math.random())
924
+ } while (document.getElementById(t));
925
+ return t
926
+ },
927
+ getSelectorFromElement: function(e) {
928
+ var n = e.getAttribute("data-target");
929
+ n && "#" !== n || (n = e.getAttribute("href") || "");
930
+ try {
931
+ return t(n).length > 0 ? n : null
932
+ } catch (t) {
933
+ return null
934
+ }
935
+ },
936
+ reflow: function(t) {
937
+ return t.offsetHeight
938
+ },
939
+ triggerTransitionEnd: function(e) {
940
+ t(e).trigger(s.end)
941
+ },
942
+ supportsTransitionEnd: function() {
943
+ return Boolean(s)
944
+ },
945
+ typeCheckConfig: function(t, o, i) {
946
+ for (var r in i)
947
+ if (i.hasOwnProperty(r)) {
948
+ var s = i[r],
949
+ a = o[r],
950
+ p = a && n(a) ? "element" : e(a);
951
+ if (!new RegExp(s).test(p)) throw new Error(t.toUpperCase() + ': Option "' + r + '" provided type "' + p + '" but expected type "' + s + '".')
952
+ }
953
+ }
954
+ };
955
+ return s = i(), t.fn.emulateTransitionEnd = r, p.supportsTransitionEnd() && (t.event.special[p.TRANSITION_END] = o()), p
956
+ }(jQuery),
957
+ _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
958
+ return typeof t
959
+ } : function(t) {
960
+ return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
961
+ },
962
+ _createClass = function() {
963
+ function t(t, e) {
964
+ for (var n = 0; n < e.length; n++) {
965
+ var o = e[n];
966
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(t, o.key, o)
967
+ }
968
+ }
969
+ return function(e, n, o) {
970
+ return n && t(e.prototype, n), o && t(e, o), e
971
+ }
972
+ }(),
973
+ Tooltip = function(t) {
974
+ if ("undefined" == typeof Popper) throw new Error("Bootstrap tooltips require Popper.js (https://popper.js.org)");
975
+ var e = "tooltip",
976
+ n = ".bs.tooltip",
977
+ o = t.fn[e],
978
+ i = new RegExp("(^|\\s)bs-tooltip\\S+", "g"),
979
+ r = {
980
+ animation: "boolean",
981
+ template: "string",
982
+ title: "(string|element|function)",
983
+ trigger: "string",
984
+ delay: "(number|object)",
985
+ html: "boolean",
986
+ selector: "(string|boolean)",
987
+ placement: "(string|function)",
988
+ offset: "(number|string)",
989
+ container: "(string|element|boolean)",
990
+ fallbackPlacement: "(string|array)"
991
+ },
992
+ s = {
993
+ AUTO: "auto",
994
+ TOP: "top",
995
+ RIGHT: "right",
996
+ BOTTOM: "bottom",
997
+ LEFT: "left"
998
+ },
999
+ a = {
1000
+ animation: !0,
1001
+ template: '<div class="tooltip" role="tooltip"><div class="mo2f_arrow"></div><div class="tooltip-inner"></div></div>',
1002
+ trigger: "hover focus",
1003
+ title: "",
1004
+ delay: 0,
1005
+ html: !1,
1006
+ selector: !1,
1007
+ placement: "top",
1008
+ offset: 0,
1009
+ container: !1,
1010
+ fallbackPlacement: "flip"
1011
+ },
1012
+ p = {
1013
+ SHOW: "show",
1014
+ OUT: "out"
1015
+ },
1016
+ u = {
1017
+ HIDE: "hide" + n,
1018
+ HIDDEN: "hidden" + n,
1019
+ SHOW: "show" + n,
1020
+ SHOWN: "shown" + n,
1021
+ INSERTED: "inserted" + n,
1022
+ CLICK: "click" + n,
1023
+ FOCUSIN: "focusin" + n,
1024
+ FOCUSOUT: "focusout" + n,
1025
+ MOUSEENTER: "mouseenter" + n,
1026
+ MOUSELEAVE: "mouseleave" + n
1027
+ },
1028
+ l = {
1029
+ FADE: "fade",
1030
+ SHOW: "show"
1031
+ },
1032
+ c = {
1033
+ TOOLTIP: ".tooltip",
1034
+ TOOLTIP_INNER: ".tooltip-inner",
1035
+ ARROW: ".mo2f_arrow"
1036
+ },
1037
+ h = {
1038
+ HOVER: "hover",
1039
+ FOCUS: "focus",
1040
+ CLICK: "click",
1041
+ MANUAL: "manual"
1042
+ },
1043
+ f = function() {
1044
+ function o(t, e) {
1045
+ _classCallCheck(this, o), this._isEnabled = !0, this._timeout = 0, this._hoverState = "", this._activeTrigger = {}, this._popper = null, this.element = t, this.config = this._getConfig(e), this.tip = null, this._setListeners()
1046
+ }
1047
+ return o.prototype.enable = function() {
1048
+ this._isEnabled = !0
1049
+ }, o.prototype.disable = function() {
1050
+ this._isEnabled = !1
1051
+ }, o.prototype.toggleEnabled = function() {
1052
+ this._isEnabled = !this._isEnabled
1053
+ }, o.prototype.toggle = function(e) {
1054
+ if (e) {
1055
+ var n = this.constructor.DATA_KEY,
1056
+ o = t(e.currentTarget).data(n);
1057
+ o || (o = new this.constructor(e.currentTarget, this._getDelegateConfig()), t(e.currentTarget).data(n, o)), o._activeTrigger.click = !o._activeTrigger.click, o._isWithActiveTrigger() ? o._enter(null, o) : o._leave(null, o)
1058
+ } else {
1059
+ if (t(this.getTipElement()).hasClass(l.SHOW)) return void this._leave(null, this);
1060
+ this._enter(null, this)
1061
+ }
1062
+ }, o.prototype.dispose = function() {
1063
+ clearTimeout(this._timeout), t.removeData(this.element, this.constructor.DATA_KEY), t(this.element).off(this.constructor.EVENT_KEY), t(this.element).closest(".modal").off("hide.bs.modal"), this.tip && t(this.tip).remove(), this._isEnabled = null, this._timeout = null, this._hoverState = null, this._activeTrigger = null, null !== this._popper && this._popper.destroy(), this._popper = null, this.element = null, this.config = null, this.tip = null
1064
+ }, o.prototype.show = function() {
1065
+ var e = this;
1066
+ if ("none" === t(this.element).css("display")) throw new Error("Please use show on visible elements");
1067
+ var n = t.Event(this.constructor.Event.SHOW);
1068
+ if (this.isWithContent() && this._isEnabled) {
1069
+ t(this.element).trigger(n);
1070
+ var i = t.contains(this.element.ownerDocument.documentElement, this.element);
1071
+ if (n.isDefaultPrevented() || !i) return;
1072
+ var r = this.getTipElement(),
1073
+ s = Util.getUID(this.constructor.NAME);
1074
+ r.setAttribute("id", s), this.element.setAttribute("aria-describedby", s), this.setContent(), this.config.animation && t(r).addClass(l.FADE);
1075
+ var a = "function" == typeof this.config.placement ? this.config.placement.call(this, r, this.element) : this.config.placement,
1076
+ u = this._getAttachment(a);
1077
+ this.addAttachmentClass(u);
1078
+ var h = !1 === this.config.container ? document.body : t(this.config.container);
1079
+ t(r).data(this.constructor.DATA_KEY, this), t.contains(this.element.ownerDocument.documentElement, this.tip) || t(r).appendTo(h), t(this.element).trigger(this.constructor.Event.INSERTED), this._popper = new Popper(this.element, r, {
1080
+ placement: u,
1081
+ modifiers: {
1082
+ offset: {
1083
+ offset: this.config.offset
1084
+ },
1085
+ flip: {
1086
+ behavior: this.config.fallbackPlacement
1087
+ },
1088
+ mo2f_arrow: {
1089
+ element: c.ARROW
1090
+ }
1091
+ },
1092
+ onCreate: function(t) {
1093
+ t.originalPlacement !== t.placement && e._handlePopperPlacementChange(t)
1094
+ },
1095
+ onUpdate: function(t) {
1096
+ e._handlePopperPlacementChange(t)
1097
+ }
1098
+ }), t(r).addClass(l.SHOW), "ontouchstart" in document.documentElement && t("body").children().on("mouseover", null, t.noop);
1099
+ var f = function() {
1100
+ e.config.animation && e._fixTransition();
1101
+ var n = e._hoverState;
1102
+ e._hoverState = null, t(e.element).trigger(e.constructor.Event.SHOWN), n === p.OUT && e._leave(null, e)
1103
+ };
1104
+ Util.supportsTransitionEnd() && t(this.tip).hasClass(l.FADE) ? t(this.tip).one(Util.TRANSITION_END, f).emulateTransitionEnd(o._TRANSITION_DURATION) : f()
1105
+ }
1106
+ }, o.prototype.hide = function(e) {
1107
+ var n = this,
1108
+ o = this.getTipElement(),
1109
+ i = t.Event(this.constructor.Event.HIDE),
1110
+ r = function() {
1111
+ n._hoverState !== p.SHOW && o.parentNode && o.parentNode.removeChild(o), n._cleanTipClass(), n.element.removeAttribute("aria-describedby"), t(n.element).trigger(n.constructor.Event.HIDDEN), null !== n._popper && n._popper.destroy(), e && e()
1112
+ };
1113
+ t(this.element).trigger(i), i.isDefaultPrevented() || (t(o).removeClass(l.SHOW), "ontouchstart" in document.documentElement && t("body").children().off("mouseover", null, t.noop), this._activeTrigger[h.CLICK] = !1, this._activeTrigger[h.FOCUS] = !1, this._activeTrigger[h.HOVER] = !1, Util.supportsTransitionEnd() && t(this.tip).hasClass(l.FADE) ? t(o).one(Util.TRANSITION_END, r).emulateTransitionEnd(150) : r(), this._hoverState = "")
1114
+ }, o.prototype.update = function() {
1115
+ null !== this._popper && this._popper.scheduleUpdate()
1116
+ }, o.prototype.isWithContent = function() {
1117
+ return Boolean(this.getTitle())
1118
+ }, o.prototype.addAttachmentClass = function(e) {
1119
+ t(this.getTipElement()).addClass("bs-tooltip-" + e)
1120
+ }, o.prototype.getTipElement = function() {
1121
+ return this.tip = this.tip || t(this.config.template)[0]
1122
+ }, o.prototype.setContent = function() {
1123
+ var e = t(this.getTipElement());
1124
+ this.setElementContent(e.find(c.TOOLTIP_INNER), this.getTitle()), e.removeClass(l.FADE + " " + l.SHOW)
1125
+ }, o.prototype.setElementContent = function(e, n) {
1126
+ var o = this.config.html;
1127
+ "object" === (void 0 === n ? "undefined" : _typeof(n)) && (n.nodeType || n.jquery) ? o ? t(n).parent().is(e) || e.empty().append(n) : e.text(t(n).text()): e[o ? "html" : "text"](n)
1128
+ }, o.prototype.getTitle = function() {
1129
+ var t = this.element.getAttribute("data-original-title");
1130
+ return t || (t = "function" == typeof this.config.title ? this.config.title.call(this.element) : this.config.title), t
1131
+ }, o.prototype._getAttachment = function(t) {
1132
+ return s[t.toUpperCase()]
1133
+ }, o.prototype._setListeners = function() {
1134
+ var e = this;
1135
+ this.config.trigger.split(" ").forEach(function(n) {
1136
+ if ("click" === n) t(e.element).on(e.constructor.Event.CLICK, e.config.selector, function(t) {
1137
+ return e.toggle(t)
1138
+ });
1139
+ else if (n !== h.MANUAL) {
1140
+ var o = n === h.HOVER ? e.constructor.Event.MOUSEENTER : e.constructor.Event.FOCUSIN,
1141
+ i = n === h.HOVER ? e.constructor.Event.MOUSELEAVE : e.constructor.Event.FOCUSOUT;
1142
+ t(e.element).on(o, e.config.selector, function(t) {
1143
+ return e._enter(t)
1144
+ }).on(i, e.config.selector, function(t) {
1145
+ return e._leave(t)
1146
+ })
1147
+ }
1148
+ t(e.element).closest(".modal").on("hide.bs.modal", function() {
1149
+ return e.hide()
1150
+ })
1151
+ }), this.config.selector ? this.config = t.extend({}, this.config, {
1152
+ trigger: "manual",
1153
+ selector: ""
1154
+ }) : this._fixTitle()
1155
+ }, o.prototype._fixTitle = function() {
1156
+ var t = _typeof(this.element.getAttribute("data-original-title"));
1157
+ (this.element.getAttribute("title") || "string" !== t) && (this.element.setAttribute("data-original-title", this.element.getAttribute("title") || ""), this.element.setAttribute("title", ""))
1158
+ }, o.prototype._enter = function(e, n) {
1159
+ var o = this.constructor.DATA_KEY;
1160
+ (n = n || t(e.currentTarget).data(o)) || (n = new this.constructor(e.currentTarget, this._getDelegateConfig()), t(e.currentTarget).data(o, n)), e && (n._activeTrigger["focusin" === e.type ? h.FOCUS : h.HOVER] = !0), t(n.getTipElement()).hasClass(l.SHOW) || n._hoverState === p.SHOW ? n._hoverState = p.SHOW : (clearTimeout(n._timeout), n._hoverState = p.SHOW, n.config.delay && n.config.delay.show ? n._timeout = setTimeout(function() {
1161
+ n._hoverState === p.SHOW && n.show()
1162
+ }, n.config.delay.show) : n.show())
1163
+ }, o.prototype._leave = function(e, n) {
1164
+ var o = this.constructor.DATA_KEY;
1165
+ (n = n || t(e.currentTarget).data(o)) || (n = new this.constructor(e.currentTarget, this._getDelegateConfig()), t(e.currentTarget).data(o, n)), e && (n._activeTrigger["focusout" === e.type ? h.FOCUS : h.HOVER] = !1), n._isWithActiveTrigger() || (clearTimeout(n._timeout), n._hoverState = p.OUT, n.config.delay && n.config.delay.hide ? n._timeout = setTimeout(function() {
1166
+ n._hoverState === p.OUT && n.hide()
1167
+ }, n.config.delay.hide) : n.hide())
1168
+ }, o.prototype._isWithActiveTrigger = function() {
1169
+ for (var t in this._activeTrigger)
1170
+ if (this._activeTrigger[t]) return !0;
1171
+ return !1
1172
+ }, o.prototype._getConfig = function(n) {
1173
+ return (n = t.extend({}, this.constructor.Default, t(this.element).data(), n)).delay && "number" == typeof n.delay && (n.delay = {
1174
+ show: n.delay,
1175
+ hide: n.delay
1176
+ }), n.title && "number" == typeof n.title && (n.title = n.title.toString()), n.content && "number" == typeof n.content && (n.content = n.content.toString()), Util.typeCheckConfig(e, n, this.constructor.DefaultType), n
1177
+ }, o.prototype._getDelegateConfig = function() {
1178
+ var t = {};
1179
+ if (this.config)
1180
+ for (var e in this.config) this.constructor.Default[e] !== this.config[e] && (t[e] = this.config[e]);
1181
+ return t
1182
+ }, o.prototype._cleanTipClass = function() {
1183
+ var e = t(this.getTipElement()),
1184
+ n = e.attr("class").match(i);
1185
+ null !== n && n.length > 0 && e.removeClass(n.join(""))
1186
+ }, o.prototype._handlePopperPlacementChange = function(t) {
1187
+ this._cleanTipClass(), this.addAttachmentClass(this._getAttachment(t.placement))
1188
+ }, o.prototype._fixTransition = function() {
1189
+ var e = this.getTipElement(),
1190
+ n = this.config.animation;
1191
+ null === e.getAttribute("x-placement") && (t(e).removeClass(l.FADE), this.config.animation = !1, this.hide(), this.show(), this.config.animation = n)
1192
+ }, o._jQueryInterface = function(e) {
1193
+ return this.each(function() {
1194
+ var n = t(this).data("bs.tooltip"),
1195
+ i = "object" === (void 0 === e ? "undefined" : _typeof(e)) && e;
1196
+ if ((n || !/dispose|hide/.test(e)) && (n || (n = new o(this, i), t(this).data("bs.tooltip", n)), "string" == typeof e)) {
1197
+ if (void 0 === n[e]) throw new Error('No method named "' + e + '"');
1198
+ n[e]()
1199
+ }
1200
+ })
1201
+ }, _createClass(o, null, [{
1202
+ key: "VERSION",
1203
+ get: function() {
1204
+ return "4.0.0-beta"
1205
+ }
1206
+ }, {
1207
+ key: "Default",
1208
+ get: function() {
1209
+ return a
1210
+ }
1211
+ }, {
1212
+ key: "NAME",
1213
+ get: function() {
1214
+ return e
1215
+ }
1216
+ }, {
1217
+ key: "DATA_KEY",
1218
+ get: function() {
1219
+ return "bs.tooltip"
1220
+ }
1221
+ }, {
1222
+ key: "Event",
1223
+ get: function() {
1224
+ return u
1225
+ }
1226
+ }, {
1227
+ key: "EVENT_KEY",
1228
+ get: function() {
1229
+ return n
1230
+ }
1231
+ }, {
1232
+ key: "DefaultType",
1233
+ get: function() {
1234
+ return r
1235
+ }
1236
+ }]), o
1237
+ }();
1238
+ return t.fn[e] = f._jQueryInterface, t.fn[e].Constructor = f, t.fn[e].noConflict = function() {
1239
+ return t.fn[e] = o, f._jQueryInterface
1240
+ }, f
1241
+ }(jQuery),
1242
+ _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t) {
1243
+ return typeof t
1244
+ } : function(t) {
1245
+ return t && "function" == typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
1246
+ },
1247
+ _createClass = function() {
1248
+ function t(t, e) {
1249
+ for (var n = 0; n < e.length; n++) {
1250
+ var o = e[n];
1251
+ o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(t, o.key, o)
1252
+ }
1253
+ }
1254
+ return function(e, n, o) {
1255
+ return n && t(e.prototype, n), o && t(e, o), e
1256
+ }
1257
+ }(),
1258
+ mo2f_popover = function(t) {
1259
+ var e = "mo2f_popover",
1260
+ n = ".bs.mo2f_popover",
1261
+ o = t.fn[e],
1262
+ i = new RegExp("(^|\\s)bs-mo2f_popover\\S+", "g"),
1263
+ r = t.extend({}, Tooltip.Default, {
1264
+ placement: "right",
1265
+ trigger: "click",
1266
+ content: "",
1267
+ template: '<div class="mo2f_popover" role="tooltip"><div class="mo2f_arrow"></div><h3 class="mo2f_popover-header"></h3><div class="mo2f_popover-body"></div></div>'
1268
+ }),
1269
+ s = t.extend({}, Tooltip.DefaultType, {
1270
+ content: "(string|element|function)"
1271
+ }),
1272
+ a = {
1273
+ FADE: "fade",
1274
+ SHOW: "show"
1275
+ },
1276
+ p = {
1277
+ TITLE: ".mo2f_popover-header",
1278
+ CONTENT: ".mo2f_popover-body"
1279
+ },
1280
+ u = {
1281
+ HIDE: "hide" + n,
1282
+ HIDDEN: "hidden" + n,
1283
+ SHOW: "show" + n,
1284
+ SHOWN: "shown" + n,
1285
+ INSERTED: "inserted" + n,
1286
+ CLICK: "click" + n,
1287
+ FOCUSIN: "focusin" + n,
1288
+ FOCUSOUT: "focusout" + n,
1289
+ MOUSEENTER: "mouseenter" + n,
1290
+ MOUSELEAVE: "mouseleave" + n
1291
+ },
1292
+ l = function(o) {
1293
+ function l() {
1294
+ return _classCallCheck(this, l), _possibleConstructorReturn(this, o.apply(this, arguments))
1295
+ }
1296
+ return _inherits(l, o), l.prototype.isWithContent = function() {
1297
+ return this.getTitle() || this._getContent()
1298
+ }, l.prototype.addAttachmentClass = function(e) {
1299
+ t(this.getTipElement()).addClass("bs-mo2f_popover-" + e)
1300
+ }, l.prototype.getTipElement = function() {
1301
+ return this.tip = this.tip || t(this.config.template)[0]
1302
+ }, l.prototype.setContent = function() {
1303
+ var e = t(this.getTipElement());
1304
+ this.setElementContent(e.find(p.TITLE), this.getTitle()), this.setElementContent(e.find(p.CONTENT), this._getContent()), e.removeClass(a.FADE + " " + a.SHOW)
1305
+ }, l.prototype._getContent = function() {
1306
+ return this.element.getAttribute("data-content") || ("function" == typeof this.config.content ? this.config.content.call(this.element) : this.config.content)
1307
+ }, l.prototype._cleanTipClass = function() {
1308
+ var e = t(this.getTipElement()),
1309
+ n = e.attr("class").match(i);
1310
+ null !== n && n.length > 0 && e.removeClass(n.join(""))
1311
+ }, l._jQueryInterface = function(e) {
1312
+ return this.each(function() {
1313
+ var n = t(this).data("bs.mo2f_popover"),
1314
+ o = "object" === (void 0 === e ? "undefined" : _typeof(e)) ? e : null;
1315
+ if ((n || !/destroy|hide/.test(e)) && (n || (n = new l(this, o), t(this).data("bs.mo2f_popover", n)), "string" == typeof e)) {
1316
+ if (void 0 === n[e]) throw new Error('No method named "' + e + '"');
1317
+ n[e]()
1318
+ }
1319
+ })
1320
+ }, _createClass(l, null, [{
1321
+ key: "VERSION",
1322
+ get: function() {
1323
+ return "4.0.0-beta"
1324
+ }
1325
+ }, {
1326
+ key: "Default",
1327
+ get: function() {
1328
+ return r
1329
+ }
1330
+ }, {
1331
+ key: "NAME",
1332
+ get: function() {
1333
+ return e
1334
+ }
1335
+ }, {
1336
+ key: "DATA_KEY",
1337
+ get: function() {
1338
+ return "bs.mo2f_popover"
1339
+ }
1340
+ }, {
1341
+ key: "Event",
1342
+ get: function() {
1343
+ return u
1344
+ }
1345
+ }, {
1346
+ key: "EVENT_KEY",
1347
+ get: function() {
1348
+ return n
1349
+ }
1350
+ }, {
1351
+ key: "DefaultType",
1352
+ get: function() {
1353
+ return s
1354
+ }
1355
+ }]), l
1356
+ }(Tooltip);
1357
+ return t.fn[e] = l._jQueryInterface, t.fn[e].Constructor = l, t.fn[e].noConflict = function() {
1358
+ return t.fn[e] = o, l._jQueryInterface
1359
+ }, l
1360
+ }(jQuery),
1361
+ bind = function(t, e) {
1362
+ return function() {
1363
+ return t.apply(e, arguments)
1364
+ }
1365
+ };
1366
+ ! function(t, e) {
1367
+ "function" == typeof define && define.amd ? define(["jquery"], function(n) {
1368
+ return t.Tour = e(n)
1369
+ }) : "object" == typeof exports ? module.exports = e(require("jquery")) : t.Tour = e(t.jQuery)
1370
+ }(window, function(t) {
1371
+ var e;
1372
+ return e = window.document,
1373
+ function() {
1374
+ function n(e) {
1375
+ this._showmo2f_popoverAndOverlay = bind(this._showmo2f_popoverAndOverlay, this);
1376
+ var n;
1377
+ try {
1378
+ n = window.localStorage
1379
+ } catch (t) {
1380
+ n = !1
1381
+ }
1382
+ this._options = t.extend({
1383
+ name: "tour",
1384
+ steps: [],
1385
+ container: "body",
1386
+ autoscroll: !0,
1387
+ keyboard: !0,
1388
+ storage: n,
1389
+ debug: !1,
1390
+ backdrop: !1,
1391
+ backdropContainer: "body",
1392
+ backdropPadding: 0,
1393
+ redirect: !0,
1394
+ orphan: !1,
1395
+ duration: !1,
1396
+ delay: !1,
1397
+ basePath: "",
1398
+ template: '<div class="mo2f_popover" role="tooltip"> <div class="mo2f_arrow" ></div> <h3 class="mo2f_popover-header" style="margin-top:0px;"></h3> <div class="mo2f_popover-body"></div> <div class="mo2f_popover-navigation"> <div class="mo2f_tour_btn-group"> &nbsp; <button class="mo2f_tour_btn mo2f_tour_btn-sm mo2f_tour_btn-secondary mo2f_tour_btn_next-success" data-role="next">Next &raquo;</button> <button class="mo2f_tour_btn mo2f_tour_btn-sm mo2f_tour_btn-secondary" data-role="pause-resume" data-pause-text="Pause" data-resume-text="Resume">Pause</button> </div>&nbsp;&nbsp; <button id="mo2f_end_tour" class="button button-primary button-large" data-role="end">End tour</button> </div> </div>',
1399
+ afterSetState: function(t, e) {},
1400
+ afterGetState: function(t, e) {},
1401
+ afterRemoveState: function(t) {},
1402
+ onStart: function(t) {},
1403
+ onEnd: function(t) {},
1404
+ onShow: function(t) {},
1405
+ onShown: function(t) {},
1406
+ onHide: function(t) {},
1407
+ onHidden: function(t) {},
1408
+ onNext: function(t) {},
1409
+ onPrev: function(t) {},
1410
+ onPause: function(t, e) {},
1411
+ onResume: function(t, e) {},
1412
+ onRedirectError: function(t) {}
1413
+ }, e), this._force = !1, this._inited = !1, this._current = null, this.backdrops = []
1414
+ }
1415
+ return n.prototype.addSteps = function(t) {
1416
+ var e, n, o;
1417
+ for (e = 0, n = t.length; e < n; e++) o = t[e], this.addStep(o);
1418
+ return this
1419
+ }, n.prototype.addStep = function(t) {
1420
+ return this._options.steps.push(t), this
1421
+ }, n.prototype.getStep = function(e) {
1422
+ if (null != this._options.steps[e]) return t.extend({
1423
+ id: "step-" + e,
1424
+ path: "",
1425
+ host: "",
1426
+ placement: "right",
1427
+ title: "",
1428
+ content: "<p></p>",
1429
+ next: e === this._options.steps.length - 1 ? -1 : e + 1,
1430
+ prev: e - 1,
1431
+ animation: !0,
1432
+ container: this._options.container,
1433
+ autoscroll: this._options.autoscroll,
1434
+ backdrop: this._options.backdrop,
1435
+ backdropContainer: this._options.backdropContainer,
1436
+ backdropPadding: this._options.backdropPadding,
1437
+ redirect: this._options.redirect,
1438
+ reflexElement: this._options.steps[e].element,
1439
+ backdropElement: this._options.steps[e].element,
1440
+ orphan: this._options.orphan,
1441
+ duration: this._options.duration,
1442
+ delay: this._options.delay,
1443
+ template: this._options.template,
1444
+ onShow: this._options.onShow,
1445
+ onShown: this._options.onShown,
1446
+ onHide: this._options.onHide,
1447
+ onHidden: this._options.onHidden,
1448
+ onNext: this._options.onNext,
1449
+ onPrev: this._options.onPrev,
1450
+ onPause: this._options.onPause,
1451
+ onResume: this._options.onResume,
1452
+ onRedirectError: this._options.onRedirectError
1453
+ }, this._options.steps[e])
1454
+ }, n.prototype.init = function(t) {
1455
+ return this._force = t, this.ended() ? (this._debug("Tour ended, init prevented."), this) : (this.setCurrentStep(), this._initMouseNavigation(), this._initKeyboardNavigation(), null !== this._current && this.showStep(this._current), this._inited = !0, this)
1456
+ }, n.prototype.start = function(t) {
1457
+ var e;
1458
+ return null == t && (t = !1), this._inited || this.init(t), null === this._current && (e = this._makePromise(null != this._options.onStart ? this._options.onStart(this) : void 0), this._callOnPromiseDone(e, this.showStep, 0)), this
1459
+ }, n.prototype.next = function() {
1460
+ var t;
1461
+ return t = this.hideStep(this._current, this._current + 1), this._callOnPromiseDone(t, this._showNextStep)
1462
+ }, n.prototype.prev = function() {
1463
+ var t;
1464
+ return t = this.hideStep(this._current, this._current - 1), this._callOnPromiseDone(t, this._showPrevStep)
1465
+ }, n.prototype.goTo = function(t) {
1466
+ var e;
1467
+ return e = this.hideStep(this._current, t), this._callOnPromiseDone(e, this.showStep, t)
1468
+ }, n.prototype.end = function() {
1469
+ var n, o;
1470
+ return n = function(n) {
1471
+ return function(o) {
1472
+ if (t(e).off("click.tour-" + n._options.name), t(e).off("keyup.tour-" + n._options.name), n._setState("end", "yes"), n._inited = !1, n._force = !1, n._clearTimer(), null != n._options.onEnd) return n._options.onEnd(n)
1473
+ }
1474
+ }(this), o = this.hideStep(this._current), this._callOnPromiseDone(o, n)
1475
+ }, n.prototype.ended = function() {
1476
+ return !this._force && !!this._getState("end")
1477
+ }, n.prototype.restart = function() {
1478
+ return this._removeState("current_step"), this._removeState("end"), this._removeState("redirect_to"), this.start()
1479
+ }, n.prototype.pause = function() {
1480
+ var t;
1481
+ return (t = this.getStep(this._current)) && t.duration ? (this._paused = !0, this._duration -= (new Date).getTime() - this._start, window.clearTimeout(this._timer), this._debug("Paused/Stopped step " + (this._current + 1) + " timer (" + this._duration + " remaining)."), null != t.onPause ? t.onPause(this, this._duration) : void 0) : this
1482
+ }, n.prototype.resume = function() {
1483
+ var t;
1484
+ return (t = this.getStep(this._current)) && t.duration ? (this._paused = !1, this._start = (new Date).getTime(), this._duration = this._duration || t.duration, this._timer = window.setTimeout(function(t) {
1485
+ return function() {
1486
+ return t._isLast() ? t.next() : t.end()
1487
+ }
1488
+ }(this), this._duration), this._debug("Started step " + (this._current + 1) + " timer with duration " + this._duration), null != t.onResume && this._duration !== t.duration ? t.onResume(this, this._duration) : void 0) : this
1489
+ }, n.prototype.hideStep = function(e, n) {
1490
+ var o, i, r, s;
1491
+ if (s = this.getStep(e)) return this._clearTimer(), r = this._makePromise(null != s.onHide ? s.onHide(this, e) : void 0), i = function(o) {
1492
+ return function(i) {
1493
+ var r, a;
1494
+ if ((r = t(s.element)).data("bs.mo2f_popover") || (r = t("body")), r.mo2f_popover("dispose").removeClass("tour-" + o._options.name + "-element tour-" + o._options.name + "-" + e + "-element").removeData("bs.mo2f_popover"), s.reflex && t(s.reflexElement).removeClass("tour-step-element-reflex").off(o._reflexEvent(s.reflex) + ".tour-" + o._options.name), s.backdrop && ((a = null != n && o.getStep(n)) && a.backdrop && a.backdropElement === s.backdropElement || o._hideOverlayElement(s)), null != s.onHidden) return s.onHidden(o)
1495
+ }
1496
+ }(this), o = s.delay.hide || s.delay, "[object Number]" === {}.toString.call(o) && o > 0 ? (this._debug("Wait " + o + " milliseconds to hide the step " + (this._current + 1)), window.setTimeout(function(t) {
1497
+ return function() {
1498
+ return t._callOnPromiseDone(r, i)
1499
+ }
1500
+ }(this), o)) : this._callOnPromiseDone(r, i), r
1501
+ }, n.prototype.showStep = function(t) {
1502
+ var n, o, i, r, s, a;
1503
+ return this.ended() ? (this._debug("Tour ended, showStep prevented."), this) : (a = this.getStep(t)) && (s = t < this._current, o = this._makePromise(null != a.onShow ? a.onShow(this, t) : void 0), this.setCurrentStep(t), n = function() {
1504
+ switch ({}.toString.call(a.path)) {
1505
+ case "[object Function]":
1506
+ return a.path();
1507
+ case "[object String]":
1508
+ return this._options.basePath + a.path;
1509
+ default:
1510
+ return a.path
1511
+ }
1512
+ }.call(this), !a.redirect || !this._isRedirect(a.host, n, e.location) || (this._redirect(a, t, n), this._isJustPathHashDifferent(a.host, n, e.location))) ? (r = function(e) {
1513
+ return function(n) {
1514
+ if (e._isOrphan(a)) {
1515
+ if (!1 === a.orphan) return e._debug("Skip the orphan step " + (e._current + 1) + ".\nOrphan option is false and the element does not exist or is hidden."), void(s ? e._showPrevStep() : e._showNextStep());
1516
+ e._debug("Show the orphan step " + (e._current + 1) + ". Orphans option is true.")
1517
+ }
1518
+ if (a.autoscroll ? e._scrollIntoView(t) : e._showmo2f_popoverAndOverlay(t), a.duration) return e.resume()
1519
+ }
1520
+ }(this), i = a.delay.show || a.delay, "[object Number]" === {}.toString.call(i) && i > 0 ? (this._debug("Wait " + i + " milliseconds to show the step " + (this._current + 1)), window.setTimeout(function(t) {
1521
+ return function() {
1522
+ return t._callOnPromiseDone(o, r)
1523
+ }
1524
+ }(this), i)) : this._callOnPromiseDone(o, r), o) : void 0
1525
+ }, n.prototype.getCurrentStep = function() {
1526
+ return this._current
1527
+ }, n.prototype.setCurrentStep = function(t) {
1528
+ return null != t ? (this._current = t, this._setState("current_step", t)) : (this._current = this._getState("current_step"), this._current = null === this._current ? null : parseInt(this._current, 10)), this
1529
+ }, n.prototype.redraw = function() {
1530
+ return this._showOverlayElement(this.getStep(this.getCurrentStep()))
1531
+ }, n.prototype._setState = function(t, e) {
1532
+ var n;
1533
+ if (this._options.storage) {
1534
+ n = this._options.name + "_" + t;
1535
+ try {
1536
+ this._options.storage.setItem(n, e)
1537
+ } catch (t) {
1538
+ t.code === DOMException.QUOTA_EXCEEDED_ERR && this._debug("LocalStorage quota exceeded. State storage failed.")
1539
+ }
1540
+ return this._options.afterSetState(n, e)
1541
+ }
1542
+ return null == this._state && (this._state = {}), this._state[t] = e
1543
+ }, n.prototype._removeState = function(t) {
1544
+ var e;
1545
+ return this._options.storage ? (e = this._options.name + "_" + t, this._options.storage.removeItem(e), this._options.afterRemoveState(e)) : null != this._state ? delete this._state[t] : void 0
1546
+ }, n.prototype._getState = function(t) {
1547
+ var e, n;
1548
+ return this._options.storage ? (e = this._options.name + "_" + t, n = this._options.storage.getItem(e)) : null != this._state && (n = this._state[t]), void 0 !== n && "null" !== n || (n = null), this._options.afterGetState(t, n), n
1549
+ }, n.prototype._showNextStep = function() {
1550
+ var t, e, n;
1551
+ return n = this.getStep(this._current), e = function(t) {
1552
+ return function(e) {
1553
+ return t.showStep(n.next)
1554
+ }
1555
+ }(this), t = this._makePromise(null != n.onNext ? n.onNext(this) : void 0), this._callOnPromiseDone(t, e)
1556
+ }, n.prototype._showPrevStep = function() {
1557
+ var t, e, n;
1558
+ return n = this.getStep(this._current), e = function(t) {
1559
+ return function(e) {
1560
+ return t.showStep(n.prev)
1561
+ }
1562
+ }(this), t = this._makePromise(null != n.onPrev ? n.onPrev(this) : void 0), this._callOnPromiseDone(t, e)
1563
+ }, n.prototype._debug = function(t) {
1564
+ if (this._options.debug) return window.console.log("Bootstrap Tour '" + this._options.name + "' | " + t)
1565
+ }, n.prototype._isRedirect = function(t, e, n) {
1566
+ var o;
1567
+ return !(null == t || "" === t || !("[object RegExp]" === {}.toString.call(t) && !t.test(n.origin) || "[object String]" === {}.toString.call(t) && this._isHostDifferent(t, n))) || (o = [n.pathname, n.search, n.hash].join(""), null != e && "" !== e && ("[object RegExp]" === {}.toString.call(e) && !e.test(o) || "[object String]" === {}.toString.call(e) && this._isPathDifferent(e, o)))
1568
+ }, n.prototype._isHostDifferent = function(t, e) {
1569
+ switch ({}.toString.call(t)) {
1570
+ case "[object RegExp]":
1571
+ return !t.test(e.origin);
1572
+ case "[object String]":
1573
+ return this._getProtocol(t) !== this._getProtocol(e.href) || this._getHost(t) !== this._getHost(e.href);
1574
+ default:
1575
+ return !0
1576
+ }
1577
+ }, n.prototype._isPathDifferent = function(t, e) {
1578
+ return this._getPath(t) !== this._getPath(e) || !this._equal(this._getQuery(t), this._getQuery(e)) || !this._equal(this._getHash(t), this._getHash(e))
1579
+ }, n.prototype._isJustPathHashDifferent = function(t, e, n) {
1580
+ var o;
1581
+ return (null == t || "" === t || !this._isHostDifferent(t, n)) && (o = [n.pathname, n.search, n.hash].join(""), "[object String]" === {}.toString.call(e) && (this._getPath(e) === this._getPath(o) && this._equal(this._getQuery(e), this._getQuery(o)) && !this._equal(this._getHash(e), this._getHash(o))))
1582
+ }, n.prototype._redirect = function(n, o, i) {
1583
+ var r;
1584
+ return t.isFunction(n.redirect) ? n.redirect.call(this, i) : (r = "[object String]" === {}.toString.call(n.host) ? "" + n.host + i : i, this._debug("Redirect to " + r), this._getState("redirect_to") !== "" + o ? (this._setState("redirect_to", "" + o), e.location.href = r) : (this._debug("Error redirection loop to " + i), this._removeState("redirect_to"), null != n.onRedirectError ? n.onRedirectError(this) : void 0))
1585
+ }, n.prototype._isOrphan = function(e) {
1586
+ return null == e.element || !t(e.element).length || t(e.element).is(":hidden") && "http://www.w3.org/2000/svg" !== t(e.element)[0].namespaceURI
1587
+ }, n.prototype._isLast = function() {
1588
+ return this._current < this._options.steps.length - 1
1589
+ }, n.prototype._showmo2f_popoverAndOverlay = function(t) {
1590
+ var e;
1591
+ if (this.getCurrentStep() === t && !this.ended()) return (e = this.getStep(t)).backdrop && this._showOverlayElement(e), this._showmo2f_popover(e, t), null != e.onShown && e.onShown(this), this._debug("Step " + (this._current + 1) + " of " + this._options.steps.length)
1592
+ }, n.prototype._showmo2f_popover = function(e, n) {
1593
+ var o, i, r;
1594
+ return t(".tour-" + this._options.name).remove(), r = t.extend({}, this._options), i = this._isOrphan(e), e.template = this._template(e, n), i && (e.element = "body", e.placement = "top"), (o = t(e.element)).addClass("tour-" + this._options.name + "-element tour-" + this._options.name + "-" + n + "-element"), e.options && t.extend(r, e.options), e.reflex && !i && t(e.reflexElement).addClass("tour-step-element-reflex").off(this._reflexEvent(e.reflex) + ".tour-" + this._options.name).on(this._reflexEvent(e.reflex) + ".tour-" + this._options.name, function(t) {
1595
+ return function() {
1596
+ return t._isLast() ? t.next() : t.end()
1597
+ }
1598
+ }(this)), o.mo2f_popover({
1599
+ placement: e.placement,
1600
+ trigger: "manual",
1601
+ title: e.title,
1602
+ content: e.content,
1603
+ html: !0,
1604
+ animation: e.animation,
1605
+ container: e.container,
1606
+ template: e.template,
1607
+ selector: e.element
1608
+ }).mo2f_popover("show"), t(o.data("bs.mo2f_popover").getTipElement()).attr("id", e.id)
1609
+ }, n.prototype._template = function(e, n) {
1610
+ var o, i, r, s, a, p;
1611
+ return p = e.template, this._isOrphan(e) && "[object Boolean]" !== {}.toString.call(e.orphan) && (p = e.orphan), a = t(t.isFunction(p) ? p(n, e) : p), o = a.find(".mo2f_popover-navigation"), r = o.find('[data-role="prev"]'), i = o.find('[data-role="next"]'), s = o.find('[data-role="pause-resume"]'), this._isOrphan(e) && a.addClass("orphan"), a.addClass("tour-" + this._options.name + " tour-" + this._options.name + "-" + n), e.reflex && a.addClass("tour-" + this._options.name + "-reflex"), e.prev < 0 && r.addClass("disabled").prop("disabled", !0).prop("tabindex", -1), e.next < 0 && i.addClass("disabled").prop("disabled", !0).prop("tabindex", -1), e.duration || s.remove(), a.clone().wrap("<div>").parent().html()
1612
+ }, n.prototype._reflexEvent = function(t) {
1613
+ return "[object Boolean]" === {}.toString.call(t) ? "click" : t
1614
+ }, n.prototype._scrollIntoView = function(e) {
1615
+ var n, o, i, r, s, a, p, u;
1616
+ if (p = this.getStep(e), !(n = t(p.element)).length) return this._showmo2f_popoverAndOverlay(e);
1617
+ switch (o = t(window), s = n.offset().top, r = n.outerHeight(), u = o.height(), a = 0, p.placement) {
1618
+ case "top":
1619
+ a = Math.max(0, s - u / 2);
1620
+ break;
1621
+ case "left":
1622
+ case "right":
1623
+ a = Math.max(0, s + r / 2 - u / 2);
1624
+ break;
1625
+ case "bottom":
1626
+ a = Math.max(0, s + r - u / 2)
1627
+ }
1628
+ return this._debug("Scroll into view. ScrollTop: " + a + ". Element offset: " + s + ". Window height: " + u + "."), i = 0, t("body, html").stop(!0, !0).animate({
1629
+ scrollTop: Math.ceil(a)
1630
+ }, function(t) {
1631
+ return function() {
1632
+ if (2 == ++i) return t._showmo2f_popoverAndOverlay(e), t._debug("Scroll into view.\nAnimation end element offset: " + n.offset().top + ".\nWindow height: " + o.height() + ".")
1633
+ }
1634
+ }(this))
1635
+ }, n.prototype._initMouseNavigation = function() {
1636
+ var n;
1637
+ return n = this, t(e).off("click.tour-" + this._options.name, ".mo2f_popover.tour-" + this._options.name + " *[data-role='prev']").off("click.tour-" + this._options.name, ".mo2f_popover.tour-" + this._options.name + " *[data-role='next']").off("click.tour-" + this._options.name, ".mo2f_popover.tour-" + this._options.name + " *[data-role='end']").off("click.tour-" + this._options.name, ".mo2f_popover.tour-" + this._options.name + " *[data-role='pause-resume']").on("click.tour-" + this._options.name, ".mo2f_popover.tour-" + this._options.name + " *[data-role='next']", function(t) {
1638
+ return function(e) {
1639
+ return e.preventDefault(), t.next()
1640
+ }
1641
+ }(this)).on("click.tour-" + this._options.name, ".mo2f_popover.tour-" + this._options.name + " *[data-role='prev']", function(t) {
1642
+ return function(e) {
1643
+ if (e.preventDefault(), t._current > 0) return t.prev()
1644
+ }
1645
+ }(this)).on("click.tour-" + this._options.name, ".mo2f_popover.tour-" + this._options.name + " *[data-role='end']", function(t) {
1646
+ return function(e) {
1647
+ return e.preventDefault(), t.end()
1648
+ }
1649
+ }(this)).on("click.tour-" + this._options.name, ".mo2f_popover.tour-" + this._options.name + " *[data-role='pause-resume']", function(e) {
1650
+ var o;
1651
+ return e.preventDefault(), (o = t(this)).text(n._paused ? o.data("pause-text") : o.data("resume-text")), n._paused ? n.resume() : n.pause()
1652
+ })
1653
+ }, n.prototype._initKeyboardNavigation = function() {
1654
+ if (this._options.keyboard) return t(e).on("keyup.tour-" + this._options.name, function(t) {
1655
+ return function(e) {
1656
+ if (e.which) switch (e.which) {
1657
+ case 39:
1658
+ return e.preventDefault(), t._isLast() ? t.next() : t.end();
1659
+ case 37:
1660
+ if (e.preventDefault(), t._current > 0) return t.prev()
1661
+ }
1662
+ }
1663
+ }(this))
1664
+ }, n.prototype._makePromise = function(e) {
1665
+ return e && t.isFunction(e.then) ? e : null
1666
+ }, n.prototype._callOnPromiseDone = function(t, e, n) {
1667
+ return t ? t.then(function(t) {
1668
+ return function(o) {
1669
+ return e.call(t, n)
1670
+ }
1671
+ }(this)) : e.call(this, n)
1672
+ }, n.prototype._showBackground = function(n, o) {
1673
+ var i, r, s, a, p, u, l, c, h;
1674
+ for (s = t(e).height(), h = t(e).width(), c = [], a = 0, p = (l = ["top", "bottom", "left", "right"]).length; a < p; a++) switch (u = l[a], i = null != (r = this.backdrops)[u] ? r[u] : r[u] = t("<div>", {
1675
+ class: "tour-backdrop " + u
1676
+ }), t(n.backdropContainer).append(i), u) {
1677
+ case "top":
1678
+ c.push(i.height(o.offset.top > 0 ? o.offset.top : 0).width(h).offset({
1679
+ top: 0,
1680
+ left: 0
1681
+ }));
1682
+ break;
1683
+ case "bottom":
1684
+ c.push(i.offset({
1685
+ top: o.offset.top + o.height,
1686
+ left: 0
1687
+ }).height(s - (o.offset.top + o.height)).width(h));
1688
+ break;
1689
+ case "left":
1690
+ c.push(i.offset({
1691
+ top: o.offset.top,
1692
+ left: 0
1693
+ }).height(o.height).width(o.offset.left > 0 ? o.offset.left : 0));
1694
+ break;
1695
+ case "right":
1696
+ c.push(i.offset({
1697
+ top: o.offset.top,
1698
+ left: o.offset.left + o.width
1699
+ }).height(o.height).width(h - (o.offset.left + o.width)));
1700
+ break;
1701
+ default:
1702
+ c.push(void 0)
1703
+ }
1704
+ return c
1705
+ }, n.prototype._showOverlayElement = function(e) {
1706
+ var n, o;
1707
+ return 0 === (n = t(e.backdropElement)).length ? o = {
1708
+ width: 0,
1709
+ height: 0,
1710
+ offset: {
1711
+ top: 0,
1712
+ left: 0
1713
+ }
1714
+ } : (o = {
1715
+ width: n.innerWidth(),
1716
+ height: n.innerHeight(),
1717
+ offset: n.offset()
1718
+ }, n.addClass("tour-step-backdrop"), e.backdropPadding && (o = this._applyBackdropPadding(e.backdropPadding, o))), this._showBackground(e, o)
1719
+ }, n.prototype._hideOverlayElement = function(e) {
1720
+ var n, o, i;
1721
+ t(e.backdropElement).removeClass("tour-step-backdrop"), i = this.backdrops;
1722
+ for (o in i)(n = i[o]) && void 0 !== n.remove && n.remove();
1723
+ return this.backdrops = []
1724
+ }, n.prototype._applyBackdropPadding = function(t, e) {
1725
+ return "object" == typeof t ? (null == t.top && (t.top = 0), null == t.right && (t.right = 0), null == t.bottom && (t.bottom = 0), null == t.left && (t.left = 0), e.offset.top = e.offset.top - t.top, e.offset.left = e.offset.left - t.left, e.width = e.width + t.left + t.right, e.height = e.height + t.top + t.bottom) : (e.offset.top = e.offset.top - t, e.offset.left = e.offset.left - t, e.width = e.width + 2 * t, e.height = e.height + 2 * t), e
1726
+ }, n.prototype._clearTimer = function() {
1727
+ return window.clearTimeout(this._timer), this._timer = null, this._duration = null
1728
+ }, n.prototype._getProtocol = function(t) {
1729
+ return (t = t.split("://")).length > 1 ? t[0] : "http"
1730
+ }, n.prototype._getHost = function(t) {
1731
+ return t = t.split("//"), (t = t.length > 1 ? t[1] : t[0]).split("/")[0]
1732
+ }, n.prototype._getPath = function(t) {
1733
+ return t.replace(/\/?$/, "").split("?")[0].split("#")[0]
1734
+ }, n.prototype._getQuery = function(t) {
1735
+ return this._getParams(t, "?")
1736
+ }, n.prototype._getHash = function(t) {
1737
+ return this._getParams(t, "#")
1738
+ }, n.prototype._getParams = function(t, e) {
1739
+ var n, o, i, r, s;
1740
+ if (1 === (r = t.split(e)).length) return {};
1741
+ for (s = {}, n = 0, o = (r = r[1].split("&")).length; n < o; n++) s[(i = (i = r[n]).split("="))[0]] = i[1] || "";
1742
+ return s
1743
+ }, n.prototype._equal = function(t, e) {
1744
+ var n, o, i, r, s, a;
1745
+ if ("[object Object]" === {}.toString.call(t) && "[object Object]" === {}.toString.call(e)) {
1746
+ if (r = Object.keys(t), s = Object.keys(e), r.length !== s.length) return !1;
1747
+ for (o in t)
1748
+ if (a = t[o], !this._equal(e[o], a)) return !1;
1749
+ return !0
1750
+ }
1751
+ if ("[object Array]" === {}.toString.call(t) && "[object Array]" === {}.toString.call(e)) {
1752
+ if (t.length !== e.length) return !1;
1753
+ for (o = n = 0, i = t.length; n < i; o = ++n)
1754
+ if (a = t[o], !this._equal(a, e[o])) return !1;
1755
+ return !0
1756
+ }
1757
+ return t === e
1758
+ }, n
1759
+ }()
1760
+ });
miniorange_2_factor_common_login.php CHANGED
@@ -838,10 +838,10 @@ function mo2f_customize_logo() { ?>
838
  function echo_js_css_files() {
839
  echo '<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>';
840
  echo '<script src="' . plugins_url( 'includes/js/bootstrap.min.js', __FILE__ ) . '" ></script>';
841
- echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/bootstrap.min.css?version=5.1.8', __FILE__ ) . '" />';
842
- echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/front_end_login.css?version=5.1.8', __FILE__ ) . '" />';
843
- echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/style_settings.css?version=5.1.8', __FILE__ ) . '" />';
844
- echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/hide-login.css?version=5.1.8', __FILE__ ) . '" />';
845
 
846
  if ( get_option( 'mo2f_personalization_ui' ) ) {
847
  echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/mo2f_login_popup_ui.css', __FILE__ ) . '" />';
838
  function echo_js_css_files() {
839
  echo '<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>';
840
  echo '<script src="' . plugins_url( 'includes/js/bootstrap.min.js', __FILE__ ) . '" ></script>';
841
+ echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/bootstrap.min.css?version=5.1.9', __FILE__ ) . '" />';
842
+ echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/front_end_login.css?version=5.1.9', __FILE__ ) . '" />';
843
+ echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/style_settings.css?version=5.1.9', __FILE__ ) . '" />';
844
+ echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/hide-login.css?version=5.1.9', __FILE__ ) . '" />';
845
 
846
  if ( get_option( 'mo2f_personalization_ui' ) ) {
847
  echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/mo2f_login_popup_ui.css', __FILE__ ) . '" />';
miniorange_2_factor_configuration.php CHANGED
@@ -36,16 +36,19 @@ function mo_2_factor_register( $user ) {
36
  <div class="wrap">
37
  <div><img style="float:left;" src="<?php echo plugins_url( 'includes/images/logo.png"', __FILE__ ); ?>"></div>
38
  <div style="display:block;font-size:23px;padding:9px 0 10px;line-height:29px; margin-left:3%">
39
- <a href="admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=2factor_setup"
40
  class="add-new-h2" <?php echo $mo2f_active_tab == '2factor_setup' ? 'nav-tab-active' : ''; ?>
41
  id="mo2f_tab1" >
42
  <?php echo $account_tab_name; ?></a>
43
- <a class="add-new-h2" href="https://faq.miniorange.com/kb/two-factor-authentication"
44
- target="_blank"><?php echo mo2f_lt( 'FAQ' ); ?></a>
 
 
45
  <?php if ( $can_display_admin_features ) { ?>
46
- <a class="twofa-license add-new-h2" id="mo2f_tab6"
47
  href="admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mo2f_pricing"
48
  ><?php echo mo2f_lt( 'Upgrade to Standard/Premium' ); ?></a>
 
49
  <?php } ?>
50
 
51
  </div>
@@ -114,7 +117,7 @@ function mo_2_factor_register( $user ) {
114
  } else if ( $can_display_admin_features && $mo2f_active_tab == 'mo2f_pricing' ) {
115
  MO2f_Utility::unset_session_variables( $session_variables );
116
  show_2_factor_pricing_page( $user );
117
- } else {
118
 
119
  MO2f_Utility::unset_session_variables( $session_variables );
120
  if ( get_option( 'mo_2factor_admin_registration_status' ) == 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' && get_option( 'mo2f_miniorange_admin' ) != $user->ID ) {
@@ -158,8 +161,8 @@ function mo_2_factor_register( $user ) {
158
  ?>
159
  </td>
160
  <td style="vertical-align:top;padding-left:1%;" id="mo2f_support_table">
161
- <?php if ( $can_display_admin_features && ! ( $mo2f_active_tab == 'mobile_configure' || $mo2f_active_tab == 'mo2f_pricing' || $mo2f_active_tab == 'mo2f_login' ) ) {
162
- // echo mo2f_support();
163
  } ?>
164
  </td>
165
  </tr>
@@ -177,6 +180,8 @@ function mo2f_show_registration_page( $user ) {
177
  <!--Register with miniOrange-->
178
  <form name="f" method="post" action="">
179
  <input type="hidden" name="option" value="mo_auth_register_customer"/>
 
 
180
  <div <?php if($is_registration) { ?>class="mo2f_proxy_setup" <?php } ?>>
181
  <?php if($is_registration) { ?>
182
  <h3><span><?php echo mo2f_lt( 'Register with miniOrange' ); ?></span></h3><hr>
@@ -198,11 +203,11 @@ function mo2f_show_registration_page( $user ) {
198
  </tr>
199
  <tr>
200
  <td><b><span class="impt">*</span><?php echo mo2f_lt( 'Password :' ); ?></b></td>
201
- <td><input class="mo2f_table_textbox" type="password" required name="password"/></td>
202
  </tr>
203
  <tr>
204
  <td><b><span class="impt">*</span><?php echo mo2f_lt( 'Confirm Password :' ); ?></b></td>
205
- <td><input class="mo2f_table_textbox" type="password" required name="confirmPassword"/></td>
206
  </tr>
207
  <tr>
208
  <td>&nbsp;</td>
@@ -218,6 +223,8 @@ function mo2f_show_registration_page( $user ) {
218
  </form>
219
  <form name="f" method="post" action="" id="mo2f_verify_customerform">
220
  <input type="hidden" name="option" value="mo2f_goto_verifycustomer">
 
 
221
  </form>
222
 
223
  <script>
@@ -238,6 +245,8 @@ function mo2f_show_otp_validation_page( $user ) {
238
  <div>
239
  <table style="border-collapse: separate; border-spacing: 0 1em;">
240
  <form name="f" method="post" id="mo_2f_otp_form" action="">
 
 
241
  <input type="hidden" name="option" value="mo_2factor_validate_otp"/>
242
  <tr>
243
  <td><b><font color="#FF0000">*</font><?php echo mo2f_lt( 'Enter OTP:' ); ?></b></td>
@@ -259,11 +268,15 @@ function mo2f_show_otp_validation_page( $user ) {
259
  <input type="hidden" name="option" value="mo_2factor_gobackto_registration_page"/>
260
  <input type="submit" name="mo2f_goback" id="mo2f_goback"
261
  value="<?php echo mo2f_lt( 'Back' ); ?>" class="button button-primary button-large"/>
 
 
262
  </td>
263
  </form>
264
  </td>
265
  </tr>
266
  <form name="f" method="post" action="" id="resend_otp_form">
 
 
267
  <input type="hidden" name="option" value="mo_2factor_resend_otp"/>
268
  </form>
269
 
@@ -353,13 +366,13 @@ function show_2_factor_addons( $current_user ) {
353
  <div class="mo2f_vertical-submenu" style='text-align:justify'>
354
  <a href="admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_addon&mo2f_sub_tab=mo2f_sub_tab_rba"
355
  class="nav-tab show_rba <?php echo $mo2f_active_sub_tab == 'mo2f_sub_tab_rba' ? 'active' : ''; ?>"
356
- style='margin-left:5px' "
357
  ><?php echo __( 'Risk Based Access', 'miniorange-2-factor-authentication' ); ?></a>
358
  <a href="admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_addon&mo2f_sub_tab=mo2f_sub_tab_personalization"
359
- class="nav-tab show_personalization <?php echo $mo2f_active_sub_tab == 'mo2f_sub_tab_personalization' ? 'active' : ''; ?>"><?php echo __( 'Personalization', 'miniorange-2-factor-authentication' ); ?></a>
360
  <a href="admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_addon&mo2f_sub_tab=mo2f_sub_tab_shortcode"
361
  class="nav-tab show_shortcode <?php echo $mo2f_active_sub_tab == 'mo2f_sub_tab_shortcode' ? 'active' : ''; ?>"
362
- style='margin-right:0px' "><?php echo __( 'Shortcode', 'miniorange-2-factor-authentication' ); ?></a>
363
  </div>
364
  <br><br><br><br>
365
  <?php if ( $mo2f_active_sub_tab == "mo2f_sub_tab_rba" ) {
@@ -419,6 +432,7 @@ function show_2_factor_addons( $current_user ) {
419
  value="<?php echo get_option( 'mo2f_host_name' ) . '/moas/initializepayment'; ?>"/>
420
  <input type="text" name="requestOrigin" id="requestOrigin"/>
421
  </form>
 
422
  <script>
423
  function mo2f_addonform(planType) {
424
  jQuery('#requestOrigin').val(planType);
@@ -557,6 +571,8 @@ function show_2_factor_proxy_setup( $user ) {
557
  <div style="float:right;">
558
  <form name="f" method="post" action="" id="mo2f_disable_proxy_setup_form">
559
  <input type="hidden" name="option" value="mo2f_disable_proxy_setup_option"/>
 
 
560
 
561
  <input type="submit" name="submit" style="float:right"
562
  value="<?php echo mo2f_lt( 'Reset Proxy Settings' ); ?>"
@@ -572,6 +588,8 @@ function show_2_factor_proxy_setup( $user ) {
572
  <br><br>
573
  <form name="f" method="post" action="">
574
  <input type="hidden" name="option" value="mo2f_save_proxy_settings"/>
 
 
575
  <table class="mo2f_settings_table">
576
  <tr>
577
 
@@ -641,7 +659,8 @@ function show_2_factor_login_settings( $user ) {
641
 
642
  <form name="f" id="login_settings_form" method="post" action="">
643
  <input type="hidden" name="option" value="mo_auth_login_settings_save"/>
644
-
 
645
  <div class="row">
646
  <h3 style="padding:10px;"><?php echo mo2f_lt( 'Select Login Screen Options' ); ?>
647
 
@@ -887,6 +906,9 @@ function mo2f_show_verify_password_page() {
887
  <!--Verify password with miniOrange-->
888
  <form name="f" method="post" action="">
889
  <input type="hidden" name="option" value="mo_auth_verify_customer"/>
 
 
 
890
  <div <?php if($is_registration) { ?>class="mo2f_proxy_setup" <?php } ?>>
891
  <?php if($is_registration) { ?>
892
  <h2><?php echo mo2f_lt( 'Sign In to your miniOrange Account' ); ?></h2><hr>
@@ -930,6 +952,8 @@ function mo2f_show_verify_password_page() {
930
  </form>
931
  <form name="f" method="post" action="" id="gobackform">
932
  <input type="hidden" name="option" value="mo_2factor_gobackto_registration_page"/>
 
 
933
  </form>
934
  <script>
935
  jQuery('#mo2f_go_back').click(function () {
36
  <div class="wrap">
37
  <div><img style="float:left;" src="<?php echo plugins_url( 'includes/images/logo.png"', __FILE__ ); ?>"></div>
38
  <div style="display:block;font-size:23px;padding:9px 0 10px;line-height:29px; margin-left:3%">
39
+ <a id="mo2f_account" href="admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=2factor_setup"
40
  class="add-new-h2" <?php echo $mo2f_active_tab == '2factor_setup' ? 'nav-tab-active' : ''; ?>
41
  id="mo2f_tab1" >
42
  <?php echo $account_tab_name; ?></a>
43
+ <a id="mo2f_faq" class="add-new-h2" href="https://faq.miniorange.com/kb/two-factor-authentication"
44
+ target="_blank"><?php echo mo2f_lt( 'FAQ' ); ?></a>
45
+ <a id="mo2f_faq" class="add-new-h2" href="https://wordpress.org/support/plugin/miniorange-2-factor-authentication"
46
+ target="_blank"><?php echo mo2f_lt( 'WordPress Forum' ); ?></a>
47
  <?php if ( $can_display_admin_features ) { ?>
48
+ <a id="mo2f_upgrade" class="twofa-license add-new-h2" id="mo2f_tab6"
49
  href="admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mo2f_pricing"
50
  ><?php echo mo2f_lt( 'Upgrade to Standard/Premium' ); ?></a>
51
+
52
  <?php } ?>
53
 
54
  </div>
117
  } else if ( $can_display_admin_features && $mo2f_active_tab == 'mo2f_pricing' ) {
118
  MO2f_Utility::unset_session_variables( $session_variables );
119
  show_2_factor_pricing_page( $user );
120
+ }else {
121
 
122
  MO2f_Utility::unset_session_variables( $session_variables );
123
  if ( get_option( 'mo_2factor_admin_registration_status' ) == 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' && get_option( 'mo2f_miniorange_admin' ) != $user->ID ) {
161
  ?>
162
  </td>
163
  <td style="vertical-align:top;padding-left:1%;" id="mo2f_support_table">
164
+ <?php if ( $can_display_admin_features && ! ( $mo2f_active_tab == 'mobile_configure' || $mo2f_active_tab == 'mo2f_pricing'|| $mo2f_active_tab == 'mo2f_support' ) ) {
165
+ echo mo2f_support();
166
  } ?>
167
  </td>
168
  </tr>
180
  <!--Register with miniOrange-->
181
  <form name="f" method="post" action="">
182
  <input type="hidden" name="option" value="mo_auth_register_customer"/>
183
+ <input type="hidden" name="miniorange_register_customer_nonce"
184
+ value="<?php echo wp_create_nonce( "miniorange-register-customer-nonce" ) ?>"/>
185
  <div <?php if($is_registration) { ?>class="mo2f_proxy_setup" <?php } ?>>
186
  <?php if($is_registration) { ?>
187
  <h3><span><?php echo mo2f_lt( 'Register with miniOrange' ); ?></span></h3><hr>
203
  </tr>
204
  <tr>
205
  <td><b><span class="impt">*</span><?php echo mo2f_lt( 'Password :' ); ?></b></td>
206
+ <td><input class="mo2f_table_textbox" type="password" required name="password" pattern="(^[(\w)*(\!\@\#\$\%\^\&\*\.\-\_)*]+$).{6,}" title="Minimum 6 characters required"/></td>
207
  </tr>
208
  <tr>
209
  <td><b><span class="impt">*</span><?php echo mo2f_lt( 'Confirm Password :' ); ?></b></td>
210
+ <td><input class="mo2f_table_textbox" type="password" required name="confirmPassword" pattern="(^[(\w)*(\!\@\#\$\%\^\&\*\.\-\_)*]+$).{6,}" title="Minimum 6 characters required" /></td>
211
  </tr>
212
  <tr>
213
  <td>&nbsp;</td>
223
  </form>
224
  <form name="f" method="post" action="" id="mo2f_verify_customerform">
225
  <input type="hidden" name="option" value="mo2f_goto_verifycustomer">
226
+ <input type="hidden" name="mo2f_goto_verifycustomer_nonce"
227
+ value="<?php echo wp_create_nonce( "mo2f-goto-verifycustomer-nonce" ) ?>"/>
228
  </form>
229
 
230
  <script>
245
  <div>
246
  <table style="border-collapse: separate; border-spacing: 0 1em;">
247
  <form name="f" method="post" id="mo_2f_otp_form" action="">
248
+ <input type="hidden" name="mo_2factor_validate_otp_nonce"
249
+ value="<?php echo wp_create_nonce( "mo-2factor-validate-otp-nonce" ) ?>"/>
250
  <input type="hidden" name="option" value="mo_2factor_validate_otp"/>
251
  <tr>
252
  <td><b><font color="#FF0000">*</font><?php echo mo2f_lt( 'Enter OTP:' ); ?></b></td>
268
  <input type="hidden" name="option" value="mo_2factor_gobackto_registration_page"/>
269
  <input type="submit" name="mo2f_goback" id="mo2f_goback"
270
  value="<?php echo mo2f_lt( 'Back' ); ?>" class="button button-primary button-large"/>
271
+ <input type="hidden" name="mo_2factor_gobackto_registration_page_nonce"
272
+ value="<?php echo wp_create_nonce( "mo-2factor-gobackto-registration-page-nonce" ) ?>"/>
273
  </td>
274
  </form>
275
  </td>
276
  </tr>
277
  <form name="f" method="post" action="" id="resend_otp_form">
278
+ <input type="hidden" name="mo_2factor_resend_otp_nonce"
279
+ value="<?php echo wp_create_nonce( "mo-2factor-resend-otp-nonce" ) ?>"/>
280
  <input type="hidden" name="option" value="mo_2factor_resend_otp"/>
281
  </form>
282
 
366
  <div class="mo2f_vertical-submenu" style='text-align:justify'>
367
  <a href="admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_addon&mo2f_sub_tab=mo2f_sub_tab_rba"
368
  class="nav-tab show_rba <?php echo $mo2f_active_sub_tab == 'mo2f_sub_tab_rba' ? 'active' : ''; ?>"
369
+ style='margin-left:5px' " id="mo2f_rba_add_on"
370
  ><?php echo __( 'Risk Based Access', 'miniorange-2-factor-authentication' ); ?></a>
371
  <a href="admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_addon&mo2f_sub_tab=mo2f_sub_tab_personalization"
372
+ class="nav-tab show_personalization <?php echo $mo2f_active_sub_tab == 'mo2f_sub_tab_personalization' ? 'active' : ''; ?>" id="mo2f_personalization_add_on"><?php echo __( 'Personalization', 'miniorange-2-factor-authentication' ); ?></a>
373
  <a href="admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_addon&mo2f_sub_tab=mo2f_sub_tab_shortcode"
374
  class="nav-tab show_shortcode <?php echo $mo2f_active_sub_tab == 'mo2f_sub_tab_shortcode' ? 'active' : ''; ?>"
375
+ style='margin-right:0px' " id="mo2f_shortcode_add_on"><?php echo __( 'Shortcode', 'miniorange-2-factor-authentication' ); ?></a>
376
  </div>
377
  <br><br><br><br>
378
  <?php if ( $mo2f_active_sub_tab == "mo2f_sub_tab_rba" ) {
432
  value="<?php echo get_option( 'mo2f_host_name' ) . '/moas/initializepayment'; ?>"/>
433
  <input type="text" name="requestOrigin" id="requestOrigin"/>
434
  </form>
435
+
436
  <script>
437
  function mo2f_addonform(planType) {
438
  jQuery('#requestOrigin').val(planType);
571
  <div style="float:right;">
572
  <form name="f" method="post" action="" id="mo2f_disable_proxy_setup_form">
573
  <input type="hidden" name="option" value="mo2f_disable_proxy_setup_option"/>
574
+ <input type="hidden" name="mo2f_disable_proxy_setup_option_nonce"
575
+ value="<?php echo wp_create_nonce( "mo2f-disable-proxy-setup-option-nonce" ) ?>"/>
576
 
577
  <input type="submit" name="submit" style="float:right"
578
  value="<?php echo mo2f_lt( 'Reset Proxy Settings' ); ?>"
588
  <br><br>
589
  <form name="f" method="post" action="">
590
  <input type="hidden" name="option" value="mo2f_save_proxy_settings"/>
591
+ <input type="hidden" name="mo2f_save_proxy_settings_nonce"
592
+ value="<?php echo wp_create_nonce( "mo2f-save-proxy-settings-nonce" ) ?>"/>
593
  <table class="mo2f_settings_table">
594
  <tr>
595
 
659
 
660
  <form name="f" id="login_settings_form" method="post" action="">
661
  <input type="hidden" name="option" value="mo_auth_login_settings_save"/>
662
+ <input type="hidden" name="mo_auth_login_settings_save_nonce"
663
+ value="<?php echo wp_create_nonce( "mo-auth-login-settings-save-nonce" ) ?>"/>
664
  <div class="row">
665
  <h3 style="padding:10px;"><?php echo mo2f_lt( 'Select Login Screen Options' ); ?>
666
 
906
  <!--Verify password with miniOrange-->
907
  <form name="f" method="post" action="">
908
  <input type="hidden" name="option" value="mo_auth_verify_customer"/>
909
+ <input type="hidden" name="miniorange_verify_customer_nonce"
910
+ value="<?php echo wp_create_nonce( "miniorange-verify-customer-nonce" ) ?>"/>
911
+
912
  <div <?php if($is_registration) { ?>class="mo2f_proxy_setup" <?php } ?>>
913
  <?php if($is_registration) { ?>
914
  <h2><?php echo mo2f_lt( 'Sign In to your miniOrange Account' ); ?></h2><hr>
952
  </form>
953
  <form name="f" method="post" action="" id="gobackform">
954
  <input type="hidden" name="option" value="mo_2factor_gobackto_registration_page"/>
955
+ <input type="hidden" name="mo_2factor_gobackto_registration_page_nonce"
956
+ value="<?php echo wp_create_nonce( "mo-2factor-gobackto-registration-page-nonce" ) ?>"/>
957
  </form>
958
  <script>
959
  jQuery('#mo2f_go_back').click(function () {
miniorange_2_factor_mobile_configuration.php CHANGED
@@ -170,6 +170,8 @@ function mo2f_show_user_otp_validation_page() {
170
  <table class="mo2f_settings_table">
171
  <form name="f" method="post" id="mo_2f_otp_form" action="">
172
  <input type="hidden" name="option" value="mo_2factor_validate_user_otp"/>
 
 
173
  <tr>
174
  <td>
175
  <b><font color="#FF0000">*</font><?php echo mo2f_lt( 'Enter OTP:' ); ?>
@@ -194,6 +196,8 @@ function mo2f_show_user_otp_validation_page() {
194
  <form name="f" method="post" action="">
195
  <td>
196
  <input type="hidden" name="option" value="mo_2factor_backto_user_registration"/>
 
 
197
  <input type="submit" name="mo2f_goback" id="mo2f_goback"
198
  value="<?php echo mo2f_lt( 'Back' ); ?>"
199
  class="button button-primary button-large"/></td>
@@ -202,6 +206,8 @@ function mo2f_show_user_otp_validation_page() {
202
  </tr>
203
  <form name="f" method="post" action="" id="resend_otp_form">
204
  <input type="hidden" name="option" value="mo_2factor_resend_user_otp"/>
 
 
205
  </form>
206
 
207
  </table>
@@ -349,6 +355,8 @@ function mo2f_show_instruction_to_allusers( $user, $mo2f_second_factor ) {
349
  <input type="submit" style="float:right"
350
  value="<?php echo mo2f_lt( 'Continue' ); ?>"
351
  class="button button-primary button-large"/>
 
 
352
  <input type="hidden" name="option" value="mo_auth_remove_account"/>
353
  </form>
354
  </div>
@@ -383,6 +391,8 @@ function mo2f_show_instruction_to_allusers( $user, $mo2f_second_factor ) {
383
  value="<?php echo mo2f_lt( 'Continue' ); ?>"
384
  class="button button-primary button-large"/>
385
  <input type="hidden" name="option" value="mo_auth_deactivate_account"/>
 
 
386
  </form>
387
  </div>
388
  </div>
@@ -524,19 +534,22 @@ function mo2f_select_2_factor_method( $user, $mo2f_second_factor ) {
524
  ?>
525
  <div class="mo2f_setup_2_factor_tab">
526
 
527
- <p style="float:right;">If you could not complete the setup process, <a style="font-weight:bold; color:limegreen" href="admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mo2f_support">click here</a> for help.</p>
528
 
529
  <?php if( $selectedMethod == 'NONE' ) { ?>
530
  <p style="float:left;" ><span style="color:limegreen;font-weight:bold"><?php echo mo2f_lt( 'HOW DO I CONFIGURE 2FA?' ); ?></span>
531
  <br>Just click on <b>Configure</b> of your preferred authentication method below.</p><br>
532
 
533
  <?php } ?>
 
 
 
534
  <br><br>
535
-
536
  <div style="text-align: center;">
537
 
538
- <p style="font-size:20px;color:darkorange;padding:10px;"><?php echo mo2f_lt( 'Selected Method - ' ); ?><?php echo $selectedMethod; ?></p>
539
- <button class="button button-primary button-large"
540
  onclick="testAuthenticationMethod('<?php echo $selectedMethod; ?>');"
541
  <?php echo $is_customer_registered && ( $selectedMethod != 'NONE' ) ? "" : " disabled "; ?>>Test
542
  Authentication Method
@@ -552,6 +565,8 @@ function mo2f_select_2_factor_method( $user, $mo2f_second_factor ) {
552
  <div style="float:right;">
553
  <form name="f" method="post" action="" id="mo2f_enable_2FA_on_login_page_form">
554
  <input type="hidden" name="option" value="mo2f_enable_2FA_on_login_page_option"/>
 
 
555
 
556
  <input type="checkbox" id="mo2f_enable_2fa_prompt_on_login_page"
557
  name="mo2f_enable_2fa_prompt_on_login_page"
@@ -624,7 +639,8 @@ function mo2f_select_2_factor_method( $user, $mo2f_second_factor ) {
624
  <div style="float:right;">
625
  <form name="f" method="post" action="" id="mo2f_enable_2FA_for_users_form">
626
  <input type="hidden" name="option" value="mo2f_enable_2FA_for_users_option"/>
627
-
 
628
  <input type="checkbox" id="mo2f_enable_2fa_for_users" name="mo2f_enable_2fa_for_users"
629
  value="1" <?php checked( get_option( 'mo2f_enable_2fa_for_users' ) == 1 );
630
 
@@ -638,7 +654,8 @@ function mo2f_select_2_factor_method( $user, $mo2f_second_factor ) {
638
  <div style="float:right;">
639
  <form name="f" method="post" action="" id="mo2f_enable_2FA_form">
640
  <input type="hidden" name="option" value="mo2f_enable_2FA_option"/>
641
-
 
642
  <input type="checkbox" id="mo2f_enable_2fa" name="mo2f_enable_2fa"
643
  value="1" <?php checked( get_option( 'mo2f_enable_2fa' ) == 1 );
644
 
@@ -675,22 +692,22 @@ function mo2f_select_2_factor_method( $user, $mo2f_second_factor ) {
675
  </div>
676
  <hr>
677
  <?php if ( $can_display_admin_features ) { ?>
678
- <div>
679
  <a class="mo2f_view_standard_plan_auth_methods" onclick="show_standard_plan_auth_methods()">
680
  <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', __FILE__ ); ?>"
681
  class="mo2f_2factor_heading_images"/>
682
- <p class="mo2f_heading_style"><?php echo mo2f_lt( 'Standard plan - Authentication methods' ); ?>
683
- *</p>
684
  </a>
685
  <?php echo mo2f_create_2fa_form( $user, "standard_plan", $is_NC ? $standard_plan_methods_new_user : $standard_plan_methods_existing_user ); ?>
686
  </div>
687
  <hr>
688
  <div>
689
- <a class="mo2f_view_premium_plan_auth_methods" onclick="show_premium_auth_methods()">
690
  <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', __FILE__ ); ?>"
691
  class="mo2f_2factor_heading_images"/>
692
  <p class="mo2f_heading_style"><?php echo mo2f_lt( 'Premium plan - Authentication methods' ); ?>
693
- *</p>
694
  </a>
695
  <?php echo mo2f_create_2fa_form( $user, "premium_plan", $is_NC ? $premium_plan_methods_new_user : $premium_plan_methods_existing_user ); ?>
696
 
@@ -707,15 +724,95 @@ function mo2f_select_2_factor_method( $user, $mo2f_second_factor ) {
707
  <form name="f" method="post" action="" id="mo2f_2factor_test_authentication_method_form">
708
  <input type="hidden" name="option" value="mo_2factor_test_authentication_method"/>
709
  <input type="hidden" name="mo2f_configured_2FA_method_test" id="mo2f_configured_2FA_method_test"/>
 
 
710
  </form>
711
 
712
  <form name="f" method="post" action="" id="mo2f_2factor_resume_flow_driven_setup_form">
713
  <input type="hidden" name="option" value="mo_2factor_resume_flow_driven_setup"/>
 
 
714
  </form>
715
 
716
  </div>
717
  </div>
 
718
  <script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
719
 
720
  function configureOrSet2ndFactor_free_plan(authMethod, action) {
721
  jQuery('#mo2f_configured_2FA_method_free_plan').val(authMethod);
@@ -834,7 +931,7 @@ function mo2f_create_2fa_form( $user, $category, $auth_methods, $can_display_adm
834
  $is_image = $auth_method == "" ? 0 :1;
835
 
836
  $form .= '<td>
837
- <div class="mo2f_thumbnail" style="height:' . $thumbnail_height . 'px;border-color:#ddd;">
838
  <div><div>
839
  <div style="width: 80px; float:left;">';
840
 
@@ -860,7 +957,7 @@ function mo2f_create_2fa_form( $user, $category, $auth_methods, $can_display_adm
860
  $form .= ';color:white">';
861
  if ( $auth_method != "Email Verification" ) {
862
  $form .= '<div class="mo2f_configure_2_factor">
863
- <button type="button" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'configure2factor\');"';
864
  $form .= $can_user_configure_2fa_method ? "" : " disabled ";
865
  $form .= '>';
866
  $form .= $is_auth_method_configured ? 'Reconfigure' : 'Configure';
@@ -868,7 +965,7 @@ function mo2f_create_2fa_form( $user, $category, $auth_methods, $can_display_adm
868
  }
869
  if ( $is_auth_method_configured && ! $is_auth_method_selected ) {
870
  $form .= '<div class="mo2f_set_2_factor">
871
- <button type="button" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'select2factor\');"';
872
  $form .= $can_user_configure_2fa_method ? "" : " disabled ";
873
  $form .= '>Set as 2-factor</button>
874
  </div>';
@@ -890,7 +987,8 @@ function mo2f_create_2fa_form( $user, $category, $auth_methods, $can_display_adm
890
  <p style="font-size:16px;margin-left: 1%">In addition to these authentication methods, for other features in this plan, <a href="admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_pricing"><i>Click here.</i></a></p>
891
  </div>';
892
 
893
- $form .= '</div>
 
894
  <input type="hidden" name="option" value="mo2f_save_' . $category . '_auth_methods" />
895
  <input type="hidden" name="mo2f_configured_2FA_method_' . $category . '" id="mo2f_configured_2FA_method_' . $category . '" />
896
  <input type="hidden" name="mo2f_selected_action_' . $category . '" id="mo2f_selected_action_' . $category . '" />
@@ -899,6 +997,8 @@ function mo2f_create_2fa_form( $user, $category, $auth_methods, $can_display_adm
899
  return $form;
900
  }
901
 
 
 
902
  function show_2_factor_pricing_page( $user ) {
903
  global $Mo2fdbQueries;
904
 
170
  <table class="mo2f_settings_table">
171
  <form name="f" method="post" id="mo_2f_otp_form" action="">
172
  <input type="hidden" name="option" value="mo_2factor_validate_user_otp"/>
173
+ <input type="hidden" name="mo_2factor_validate_user_otp_nonce"
174
+ value="<?php echo wp_create_nonce( "mo-2factor-validate-user-otp-nonce" ) ?>"/>
175
  <tr>
176
  <td>
177
  <b><font color="#FF0000">*</font><?php echo mo2f_lt( 'Enter OTP:' ); ?>
196
  <form name="f" method="post" action="">
197
  <td>
198
  <input type="hidden" name="option" value="mo_2factor_backto_user_registration"/>
199
+ <input type="hidden" name="mo_2factor_backto_user_registration_nonce"
200
+ value="<?php echo wp_create_nonce( "mo-2factor-backto-user-registration-nonce" ) ?>"/>
201
  <input type="submit" name="mo2f_goback" id="mo2f_goback"
202
  value="<?php echo mo2f_lt( 'Back' ); ?>"
203
  class="button button-primary button-large"/></td>
206
  </tr>
207
  <form name="f" method="post" action="" id="resend_otp_form">
208
  <input type="hidden" name="option" value="mo_2factor_resend_user_otp"/>
209
+ <input type="hidden" name="mo_2factor_resend_user_otp_nonce"
210
+ value="<?php echo wp_create_nonce( "mo-2factor-resend-user-otp-nonce" ) ?>"/>
211
  </form>
212
 
213
  </table>
355
  <input type="submit" style="float:right"
356
  value="<?php echo mo2f_lt( 'Continue' ); ?>"
357
  class="button button-primary button-large"/>
358
+ <input type="hidden" name="mo_auth_remove_account_nonce"
359
+ value="<?php echo wp_create_nonce( "mo-auth-remove-account-nonce" ) ?>"/>
360
  <input type="hidden" name="option" value="mo_auth_remove_account"/>
361
  </form>
362
  </div>
391
  value="<?php echo mo2f_lt( 'Continue' ); ?>"
392
  class="button button-primary button-large"/>
393
  <input type="hidden" name="option" value="mo_auth_deactivate_account"/>
394
+ <input type="hidden" name="mo_auth_deactivate_account_nonce"
395
+ value="<?php echo wp_create_nonce( "mo-auth-deactivate-account-nonce" ) ?>"/>
396
  </form>
397
  </div>
398
  </div>
534
  ?>
535
  <div class="mo2f_setup_2_factor_tab">
536
 
537
+ <p style="float:right;">If you could not complete the setup process, <a style="font-weight:bold; color:limegreen" id="mo2f_support_form" href="admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mo2f_support">CLICK HERE</a> for help.</p>
538
 
539
  <?php if( $selectedMethod == 'NONE' ) { ?>
540
  <p style="float:left;" ><span style="color:limegreen;font-weight:bold"><?php echo mo2f_lt( 'HOW DO I CONFIGURE 2FA?' ); ?></span>
541
  <br>Just click on <b>Configure</b> of your preferred authentication method below.</p><br>
542
 
543
  <?php } ?>
544
+ <br><br><br>
545
+ <?php if(get_option( 'mo2f_is_NC' ) && get_option( 'mo2f_is_NNC' )){?>
546
+ <button type="button" id="mo2f_restart_tour" class="button button-primary button-large"style="float:right;" onclick="restart_tour();"><i class="fa fa-refresh"></i> Restart Tour</button>
547
  <br><br>
548
+ <?php } ?>
549
  <div style="text-align: center;">
550
 
551
+ <p style="font-size:20px;color:darkorange;padding:10px;" ><span id="mo2f_selected_method"><?php echo mo2f_lt( 'Selected Method - ' ); ?><?php echo $selectedMethod; ?></span></p>
552
+ <button class="button button-primary button-large" id="test"
553
  onclick="testAuthenticationMethod('<?php echo $selectedMethod; ?>');"
554
  <?php echo $is_customer_registered && ( $selectedMethod != 'NONE' ) ? "" : " disabled "; ?>>Test
555
  Authentication Method
565
  <div style="float:right;">
566
  <form name="f" method="post" action="" id="mo2f_enable_2FA_on_login_page_form">
567
  <input type="hidden" name="option" value="mo2f_enable_2FA_on_login_page_option"/>
568
+ <input type="hidden" name="mo2f_enable_2FA_on_login_page_option_nonce"
569
+ value="<?php echo wp_create_nonce( "mo2f-enable-2FA-on-login-page-option-nonce" ) ?>"/>
570
 
571
  <input type="checkbox" id="mo2f_enable_2fa_prompt_on_login_page"
572
  name="mo2f_enable_2fa_prompt_on_login_page"
639
  <div style="float:right;">
640
  <form name="f" method="post" action="" id="mo2f_enable_2FA_for_users_form">
641
  <input type="hidden" name="option" value="mo2f_enable_2FA_for_users_option"/>
642
+ <input type="hidden" name="mo2f_enable_2FA_for_users_option_nonce"
643
+ value="<?php echo wp_create_nonce( "mo2f-enable-2FA-for-users-option-nonce" ) ?>"/>
644
  <input type="checkbox" id="mo2f_enable_2fa_for_users" name="mo2f_enable_2fa_for_users"
645
  value="1" <?php checked( get_option( 'mo2f_enable_2fa_for_users' ) == 1 );
646
 
654
  <div style="float:right;">
655
  <form name="f" method="post" action="" id="mo2f_enable_2FA_form">
656
  <input type="hidden" name="option" value="mo2f_enable_2FA_option"/>
657
+ <input type="hidden" name="mo2f_enable_2FA_option_nonce"
658
+ value="<?php echo wp_create_nonce( "mo2f-enable-2FA-option-nonce" ) ?>"/>
659
  <input type="checkbox" id="mo2f_enable_2fa" name="mo2f_enable_2fa"
660
  value="1" <?php checked( get_option( 'mo2f_enable_2fa' ) == 1 );
661
 
692
  </div>
693
  <hr>
694
  <?php if ( $can_display_admin_features ) { ?>
695
+ <div id="mo2f_standard_plan">
696
  <a class="mo2f_view_standard_plan_auth_methods" onclick="show_standard_plan_auth_methods()">
697
  <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', __FILE__ ); ?>"
698
  class="mo2f_2factor_heading_images"/>
699
+ <p class="mo2f_heading_style"><span > <?php echo mo2f_lt( 'Standard plan - Authentication methods' ); ?>
700
+ *</span></p>
701
  </a>
702
  <?php echo mo2f_create_2fa_form( $user, "standard_plan", $is_NC ? $standard_plan_methods_new_user : $standard_plan_methods_existing_user ); ?>
703
  </div>
704
  <hr>
705
  <div>
706
+ <span id="mo2f_premium_plan"> <a class="mo2f_view_premium_plan_auth_methods" onclick="show_premium_auth_methods()">
707
  <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', __FILE__ ); ?>"
708
  class="mo2f_2factor_heading_images"/>
709
  <p class="mo2f_heading_style"><?php echo mo2f_lt( 'Premium plan - Authentication methods' ); ?>
710
+ *</span></p>
711
  </a>
712
  <?php echo mo2f_create_2fa_form( $user, "premium_plan", $is_NC ? $premium_plan_methods_new_user : $premium_plan_methods_existing_user ); ?>
713
 
724
  <form name="f" method="post" action="" id="mo2f_2factor_test_authentication_method_form">
725
  <input type="hidden" name="option" value="mo_2factor_test_authentication_method"/>
726
  <input type="hidden" name="mo2f_configured_2FA_method_test" id="mo2f_configured_2FA_method_test"/>
727
+ <input type="hidden" name="mo_2factor_test_authentication_method_nonce"
728
+ value="<?php echo wp_create_nonce( "mo-2factor-test-authentication-method-nonce" ) ?>"/>
729
  </form>
730
 
731
  <form name="f" method="post" action="" id="mo2f_2factor_resume_flow_driven_setup_form">
732
  <input type="hidden" name="option" value="mo_2factor_resume_flow_driven_setup"/>
733
+ <input type="hidden" name="mo_2factor_resume_flow_driven_setup_nonce"
734
+ value="<?php echo wp_create_nonce( "mo-2factor-resume-flow-driven-setup-nonce" ) ?>"/>
735
  </form>
736
 
737
  </div>
738
  </div>
739
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
740
  <script>
741
+ <?php if(get_option( 'mo2f_is_NC' ) && get_option( 'mo2f_is_NNC' )){?>
742
+ function restart_tour() {
743
+
744
+ tour.restart();
745
+ }
746
+
747
+ var tour = new Tour({
748
+ name: "tour",
749
+ steps: [
750
+ {
751
+ element: "#GoogleAuthenticator_thumbnail_2_factor",
752
+ title: "Google Authenticator Method",
753
+ content: "Select the authentication method you wish to configure, for eg., Google Authenticator.",
754
+ backdrop:'body',
755
+ backdropPadding:'6'
756
+ }, {
757
+ element: "#GoogleAuthenticator_configuration",
758
+ title: "Configure Second Factor",
759
+ content: "Click here to Configure Google Authenticator Method on your phone.",
760
+ backdrop:'body',
761
+ backdropPadding:'6'
762
+ }, {
763
+ element: "#mo2f_selected_method",
764
+ title: "Selected Authentication Method",
765
+ content: "After the configuration, Google Authenticator will be set as your 2FA method.",
766
+ onPrev:function(tour){
767
+ jQuery("#mo2f_free_plan_auth_methods").show();
768
+ jQuery("#mo2f_standard_plan_auth_methods").hide();
769
+ jQuery("#mo2f_premium_plan_auth_methods").hide();
770
+ },
771
+ backdrop:'body',
772
+ backdropPadding:'6'
773
+ }
774
+ ,{
775
+ element: "#test",
776
+ title: "Test Configured Method",
777
+ content: "Please test the 2FA method you configured, to ensure it works.",
778
+ backdrop:'body',
779
+ backdropPadd ing:'6'
780
+ }
781
+ , {
782
+ element: "#mo2f_support_form",
783
+ title: "Need Any Help?",
784
+ content: "Click here to reach us anytime you need any help with the plugin.",
785
+ backdrop:'body',
786
+ backdropPadding:'6'
787
+ }
788
+ ,{
789
+ element: "#mo2f_upgrade",
790
+ title: "Premium Plans",
791
+ content: "For the Standard & Premium features we provide, click here to view & upgrade.",
792
+ placement: 'bottom',
793
+ backdrop:'body',
794
+ backdropPadding:'6'
795
+ }
796
+ ,
797
+ {
798
+ element: "#mo2f_restart_tour",
799
+ title: "Restart Tour",
800
+ content: "Click here to restart the tour whenever you wish.",
801
+ backdrop:'body',
802
+ backdropPadding:'6'
803
+ }
804
+
805
+
806
+ ]});
807
+
808
+ // Initialize the tour
809
+ tour.init();
810
+
811
+ // Start the tour
812
+ tour.start();
813
+
814
+ <?php } ?>
815
+
816
 
817
  function configureOrSet2ndFactor_free_plan(authMethod, action) {
818
  jQuery('#mo2f_configured_2FA_method_free_plan').val(authMethod);
931
  $is_image = $auth_method == "" ? 0 :1;
932
 
933
  $form .= '<td>
934
+ <div class="mo2f_thumbnail" id="'.$auth_method_abr.'_thumbnail_2_factor" style="height:' . $thumbnail_height . 'px;border-color:#ddd;">
935
  <div><div>
936
  <div style="width: 80px; float:left;">';
937
 
957
  $form .= ';color:white">';
958
  if ( $auth_method != "Email Verification" ) {
959
  $form .= '<div class="mo2f_configure_2_factor">
960
+ <button type="button" id="'.$auth_method_abr.'_configuration" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'configure2factor\');"';
961
  $form .= $can_user_configure_2fa_method ? "" : " disabled ";
962
  $form .= '>';
963
  $form .= $is_auth_method_configured ? 'Reconfigure' : 'Configure';
965
  }
966
  if ( $is_auth_method_configured && ! $is_auth_method_selected ) {
967
  $form .= '<div class="mo2f_set_2_factor">
968
+ <button type="button" id="'.$auth_method_abr.'_set_2_factor" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'select2factor\');"';
969
  $form .= $can_user_configure_2fa_method ? "" : " disabled ";
970
  $form .= '>Set as 2-factor</button>
971
  </div>';
987
  <p style="font-size:16px;margin-left: 1%">In addition to these authentication methods, for other features in this plan, <a href="admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_pricing"><i>Click here.</i></a></p>
988
  </div>';
989
 
990
+ $form .= '</div> <input type="hidden" name="miniorange_save_form_auth_methods_nonce"
991
+ value="'. wp_create_nonce( "miniorange-save-form-auth-methods-nonce" ) .'"/>
992
  <input type="hidden" name="option" value="mo2f_save_' . $category . '_auth_methods" />
993
  <input type="hidden" name="mo2f_configured_2FA_method_' . $category . '" id="mo2f_configured_2FA_method_' . $category . '" />
994
  <input type="hidden" name="mo2f_selected_action_' . $category . '" id="mo2f_selected_action_' . $category . '" />
997
  return $form;
998
  }
999
 
1000
+
1001
+
1002
  function show_2_factor_pricing_page( $user ) {
1003
  global $Mo2fdbQueries;
1004
 
miniorange_2_factor_settings.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: miniOrange 2 Factor Authentication
4
  * Plugin URI: https://miniorange.com
5
  * Description: This plugin provides various two-factor authentication methods as an additional layer of security after the default wordpress login. We Support Google Authenticator, QR Code, Push Notification, Soft Token and Security Questions(KBA) for 1 User in the free version of the plugin.
6
- * Version: 5.1.8
7
  * Author: miniOrange
8
  * Author URI: https://miniorange.com
9
  * License: GPL2
@@ -171,7 +171,12 @@ class Miniorange_Authentication {
171
  }
172
 
173
  function mo2f_update_db_check() {
174
-
 
 
 
 
 
175
  global $Mo2fdbQueries;
176
  $user_id = get_option( 'mo2f_miniorange_admin' );
177
  $current_db_version = get_option( 'mo2f_dbversion' );
@@ -434,20 +439,21 @@ class Miniorange_Authentication {
434
  }
435
 
436
  function mo_2_factor_enable_frontend_style() {
437
- wp_enqueue_style( 'mo2f_frontend_login_style', plugins_url( 'includes/css/front_end_login.css?version=5.1.8', __FILE__ ) );
438
- wp_enqueue_style( 'bootstrap_style', plugins_url( 'includes/css/bootstrap.min.css?version=5.1.8', __FILE__ ) );
439
- wp_enqueue_style( 'mo_2_factor_admin_settings_phone_style', plugins_url( 'includes/css/phone.css?version=5.1.8', __FILE__ ) );
440
  wp_enqueue_style( 'mo_2_factor_wpb-fa', plugins_url( 'includes/css/font-awesome.min.css', __FILE__ ) );
441
- wp_enqueue_style( 'mo2f_login_popup_style', plugins_url( 'includes/css/mo2f_login_popup_ui.css?version=5.1.8', __FILE__ ) );
442
  }
443
 
444
  function plugin_settings_style( $mo2fa_hook_page ) {
445
  if ( 'toplevel_page_miniOrange_2_factor_settings' != $mo2fa_hook_page ) {
446
  return;
447
  }
448
- wp_enqueue_style( 'mo_2_factor_admin_settings_style', plugins_url( 'includes/css/style_settings.css?version=5.1.8', __FILE__ ) );
449
- wp_enqueue_style( 'mo_2_factor_admin_settings_phone_style', plugins_url( 'includes/css/phone.css?version=5.1.8', __FILE__ ) );
450
- wp_enqueue_style( 'bootstrap_style', plugins_url( 'includes/css/bootstrap.min.css?version=5.1.8', __FILE__ ) );
 
451
  wp_enqueue_style( 'mo_2_factor_wpb-fa', plugins_url( 'includes/css/font-awesome.min.css', __FILE__ ) );
452
  }
453
 
@@ -458,6 +464,8 @@ class Miniorange_Authentication {
458
  wp_enqueue_script( 'jquery' );
459
  wp_enqueue_script( 'mo_2_factor_admin_settings_phone_script', plugins_url( 'includes/js/phone.js', __FILE__ ) );
460
  wp_enqueue_script( 'bootstrap_script', plugins_url( 'includes/js/bootstrap.min.js', __FILE__ ) );
 
 
461
  }
462
 
463
  function miniorange_auth_save_settings() {
@@ -479,32 +487,61 @@ class Miniorange_Authentication {
479
  if ( current_user_can( 'manage_options' ) ) {
480
 
481
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_deactivate_account" ) {
482
- $url = admin_url( 'plugins.php' );
483
- wp_redirect( $url );
 
 
 
 
 
 
 
 
484
  }
485
 
486
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_remove_account" ) {
487
- update_option( 'mo2f_register_with_another_email', 1 );
488
- $this->mo_auth_deactivate();
 
 
 
 
 
 
 
489
  }
490
 
491
 
492
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo2f_save_proxy_settings" ) {
493
- $proxyHost = $_POST['proxyHost'];
494
- $portNumber = $_POST['portNumber'];
495
- $proxyUsername = $_POST['proxyUsername'];
496
- $proxyPassword = $_POST['proxyPass'];
497
-
498
- update_option( 'mo2f_proxy_host', $proxyHost );
499
- update_option( 'mo2f_port_number', $portNumber );
500
- update_option( 'mo2f_proxy_username', $proxyUsername );
501
- update_option( 'mo2f_proxy_password', $proxyPassword );
502
- update_option( 'mo2f_message', 'Proxy settings saved successfully.' );
503
- $this->mo_auth_show_success_message();
 
 
 
 
 
 
 
504
 
505
  }
506
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_register_customer" ) { //register the admin to miniOrange
 
 
 
 
 
507
 
 
 
508
  //validate and sanitize
509
  $email = '';
510
  $password = '';
@@ -557,152 +594,184 @@ class Miniorange_Authentication {
557
  }
558
  }
559
  }
 
560
 
561
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo2f_goto_verifycustomer" ) {
562
- $Mo2fdbQueries->insert_user( $user_id, array( 'user_id' => $user_id ) );
563
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ENTER_YOUR_EMAIL_PASSWORD" ) );
564
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_VERIFY_CUSTOMER' ) );
565
-
 
 
 
 
 
 
566
  }
567
 
568
 
569
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo_2factor_gobackto_registration_page' ) { //back to registration page for admin
570
- delete_option( 'mo2f_email' );
571
- delete_option( 'mo2f_password' );
572
- update_option( 'mo2f_message', "" );
 
 
 
 
 
 
573
 
574
- MO2f_Utility::unset_session_variables( 'mo2f_transactionId' );
575
- delete_option( 'mo2f_transactionId' );
576
- delete_user_meta( $user->ID, 'mo2f_sms_otp_count' );
577
- delete_user_meta( $user->ID, 'mo2f_email_otp_count' );
578
- delete_user_meta( $user->ID, 'mo2f_email_otp_count' );
579
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'REGISTRATION_STARTED' ) );
 
580
 
581
  }
582
 
583
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_registration_closed' ) {
584
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => '' ) );
585
- delete_user_meta( $user->ID, 'register_account' );
 
 
 
 
 
 
 
586
  }
587
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_verify_customer" ) { //register the admin to miniOrange if already exist
588
 
589
- //validation and sanitization
590
- $email = '';
591
- $password = '';
592
- $Mo2fdbQueries->insert_user( $user_id, array( 'user_id' => $user_id ) );
593
-
594
 
595
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['email'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['password'] ) ) {
596
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
597
- $this->mo_auth_show_error_message();
598
-
599
- return;
600
  } else {
601
- $email = sanitize_email( $_POST['email'] );
602
- $password = sanitize_text_field( $_POST['password'] );
603
- }
 
 
604
 
605
- update_option( 'mo2f_email', $email );
606
- update_option( 'mo2f_password', stripslashes( $password ) );
607
- $customer = new Customer_Setup();
608
- $content = $customer->get_customer_key();
609
- $customerKey = json_decode( $content, true );
610
- if ( json_last_error() == JSON_ERROR_NONE ) {
611
- if ( is_array( $customerKey ) && array_key_exists( "status", $customerKey ) && $customerKey['status'] == 'ERROR' ) {
612
- update_option( 'mo2f_message', Mo2fConstants::langTranslate( $customerKey['message'] ) );
613
  $this->mo_auth_show_error_message();
614
- } else if ( is_array( $customerKey ) ) {
615
- if ( isset( $customerKey['id'] ) && ! empty( $customerKey['id'] ) ) {
616
- update_option( 'mo2f_customerKey', $customerKey['id'] );
617
- update_option( 'mo2f_api_key', $customerKey['apiKey'] );
618
- update_option( 'mo2f_customer_token', $customerKey['token'] );
619
- update_option( 'mo2f_app_secret', $customerKey['appSecret'] );
620
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo2f_user_phone' => $customerKey['phone'] ) );
621
- update_option( 'mo2f_miniorange_admin', $user->ID );
622
-
623
- $mo2f_emailVerification_config_status = get_option( 'mo2f_is_NC' ) == 0 ? true : false;
624
 
625
- delete_option( 'mo2f_password' );
626
- update_option( 'mo_2factor_admin_registration_status', 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' );
 
 
 
627
 
628
- $Mo2fdbQueries->update_user_details( $user->ID, array(
629
- 'mo2f_EmailVerification_config_status' => $mo2f_emailVerification_config_status,
630
- 'mo2f_user_email' => get_option( 'mo2f_email' ),
631
- 'user_registration_with_miniorange' => 'SUCCESS',
632
- 'mo2f_2factor_enable_2fa_byusers' => 1,
633
- ) );
634
- $mo_2factor_user_registration_status = 'MO_2_FACTOR_PLUGIN_SETTINGS';
635
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
636
- $configured_2FA_method = 'NONE';
637
- $user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
638
- $enduser = new Two_Factor_Setup();
639
- $userinfo = json_decode( $enduser->mo2f_get_userinfo( $user_email ), true );
 
 
 
 
 
 
640
 
641
- $mo2f_second_factor = 'NONE';
642
- if ( json_last_error() == JSON_ERROR_NONE ) {
643
- if ( $userinfo['status'] == 'SUCCESS' ) {
644
- $mo2f_second_factor = mo2f_update_and_sync_user_two_factor( $user->ID, $userinfo );
645
 
646
- }
647
- }
648
- if ( $mo2f_second_factor != 'NONE' ) {
649
- $configured_2FA_method = MO2f_Utility::mo2f_decode_2_factor( $mo2f_second_factor, "servertowpdb" );
650
 
651
- if ( get_option( 'mo2f_is_NC' ) == 0 ) {
 
 
 
 
 
 
 
 
 
 
 
652
 
653
- $auth_method_abr = str_replace( ' ', '', $configured_2FA_method );
654
- $Mo2fdbQueries->update_user_details( $user->ID, array(
655
- 'mo2f_configured_2FA_method' => $configured_2FA_method,
656
- 'mo2f_' . $auth_method_abr . '_config_status' => true
657
- ) );
658
 
659
- } else {
660
- if ( in_array( $configured_2FA_method, array(
661
- 'Email Verification',
662
- 'Authy Authenticator',
663
- 'OTP over SMS'
664
- ) ) ) {
665
- $enduser->mo2f_update_userinfo( $user_email, 'NONE', null, '', true );
666
  }
667
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
668
 
669
 
670
- }
671
 
672
- $mo2f_message = Mo2fConstants:: langTranslate( "ACCOUNT_RETRIEVED_SUCCESSFULLY" );
673
- if ( $configured_2FA_method != 'NONE' && get_option( 'mo2f_is_NC' ) == 0 ) {
674
- $mo2f_message .= ' <b>' . $configured_2FA_method . '</b> ' . Mo2fConstants:: langTranslate( "DEFAULT_2ND_FACTOR" ) . '.';
675
- }
676
- $mo2f_message .= ' ' . '<a href=\"admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mobile_configure\" >' . Mo2fConstants:: langTranslate( "CLICK_HERE" ) . '</a> ' . Mo2fConstants:: langTranslate( "CONFIGURE_2FA" );
677
 
678
- delete_user_meta( $user->ID, 'register_account' );
679
 
680
- $mo2f_customer_selected_plan = get_option( 'mo2f_customer_selected_plan' );
681
- if ( ! empty( $mo2f_customer_selected_plan ) ) {
682
- delete_option( 'mo2f_customer_selected_plan' );
683
- header( 'Location: admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_pricing' );
684
- } else if ( $mo2f_second_factor == 'NONE' ) {
685
- update_user_meta( $user->ID, 'configure_2FA', 1 );
686
- }
687
 
688
 
689
- update_option( 'mo2f_message', $mo2f_message );
690
- } else {
691
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_EMAIL_OR_PASSWORD" ) );
692
- $mo_2factor_user_registration_status = 'MO_2_FACTOR_VERIFY_CUSTOMER';
693
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
 
 
694
 
695
  }
 
 
 
 
696
 
697
  }
698
- } else {
699
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_EMAIL_OR_PASSWORD" ) );
700
- $mo_2factor_user_registration_status = 'MO_2_FACTOR_VERIFY_CUSTOMER';
701
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
702
 
 
703
  }
704
-
705
- delete_option( 'mo2f_password' );
706
  }
707
 
708
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo_2factor_phone_verification' ) { //at registration time
@@ -739,25 +808,35 @@ class Miniorange_Authentication {
739
  }
740
 
741
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_resend_otp" ) { //resend OTP over email for admin
742
- $customer = new Customer_Setup();
743
- $content = json_decode( $customer->send_otp_token( get_option( 'mo2f_email' ), 'EMAIL', $defaultCustomerKey, $defaultApiKey ), true );
744
- if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) {
745
- if ( get_user_meta( $user->ID, 'mo2f_email_otp_count', true ) ) {
746
- update_user_meta( $user->ID, 'mo2f_email_otp_count', get_user_meta( $user->ID, 'mo2f_email_otp_count', true ) + 1 );
747
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "RESENT_OTP" ) . ' <b>( ' . get_user_meta( $user->ID, 'mo2f_email_otp_count', true ) . ' )</b> to <b>' . ( get_option( 'mo2f_email' ) ) . '</b> ' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
  } else {
749
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "OTP_SENT" ) . '<b> ' . ( get_option( 'mo2f_email' ) ) . ' </b>' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
750
- update_user_meta( $user->ID, 'mo2f_email_otp_count', 1 );
 
 
751
  }
752
- $mo_2factor_user_registration_status = 'MO_2_FACTOR_OTP_DELIVERED_SUCCESS';
753
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
754
- update_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account', $content['txId'] );
755
- $this->mo_auth_show_success_message();
756
- } else {
757
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_EMAIL" ) );
758
- $mo_2factor_user_registration_status = 'MO_2_FACTOR_OTP_DELIVERED_FAILURE';
759
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
760
- $this->mo_auth_show_error_message();
761
  }
762
 
763
 
@@ -771,37 +850,46 @@ class Miniorange_Authentication {
771
 
772
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_validate_otp" ) { //validate OTP over email for admin
773
 
774
- //validation and sanitization
775
- $otp_token = '';
776
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
777
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
778
- $this->mo_auth_show_error_message();
779
 
780
- return;
781
  } else {
782
- $otp_token = sanitize_text_field( $_POST['otp_token'] );
783
- }
 
 
 
784
 
785
- $customer = new Customer_Setup();
 
 
 
786
 
787
- $transactionId = get_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account', true );
788
 
789
- $content = json_decode( $customer->validate_otp_token( 'EMAIL', null, $transactionId, $otp_token, $defaultCustomerKey, $defaultApiKey ), true );
790
 
791
- if ( $content['status'] == 'ERROR' ) {
792
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $content['message'] ) );
793
 
794
- } else {
 
795
 
796
- if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated
797
- $this->mo2f_create_customer( $user );
798
- delete_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account' );
799
- delete_user_meta( $user->ID, 'register_account' );
800
- update_user_meta( $user->ID, 'configure_2FA', 1 );
801
- } else { // OTP Validation failed.
802
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
803
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_OTP_DELIVERED_FAILURE' ) );
804
 
 
 
 
 
 
 
 
 
 
 
805
  }
806
  }
807
  }
@@ -809,71 +897,90 @@ class Miniorange_Authentication {
809
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_validate_user_otp" ) { //validate OTP over email for additional admin
810
 
811
  //validation and sanitization
812
- $otp_token = '';
813
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
814
- update_option( 'mo2f_message', 'All the fields are required. Please enter valid entries.' );
815
- $this->mo_auth_show_error_message();
 
816
 
817
- return;
818
  } else {
819
- $otp_token = sanitize_text_field( $_POST['otp_token'] );
820
- }
 
 
821
 
822
- $user_email = get_user_meta( $user->ID, 'user_email', true );
 
 
 
823
 
824
- //if(!MO2f_Utility::check_if_email_is_already_registered($user_email)){
825
- $customer = new Customer_Setup();
826
- $mo2f_transactionId = isset( $_SESSION['mo2f_transactionId'] ) && ! empty( $_SESSION['mo2f_transactionId'] ) ? $_SESSION['mo2f_transactionId'] : get_option( 'mo2f_transactionId' );
827
 
828
- $content = json_decode( $customer->validate_otp_token( 'EMAIL', '', $mo2f_transactionId, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
 
 
829
 
830
- if ( $content['status'] == 'ERROR' ) {
831
- update_option( 'mo2f_message', $content['message'] );
832
- $this->mo_auth_show_error_message();
833
- } else {
834
- if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated and generate QRCode
835
- $this->mo2f_create_user( $user, $user_email );
836
- delete_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account' );
837
- } else {
838
- update_option( 'mo2f_message', 'Invalid OTP. Please try again.' );
839
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_OTP_DELIVERED_FAILURE' ) );
840
  $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
 
841
  }
 
 
 
 
842
  }
843
- /*}else{
844
- update_option('mo2f_message','The email is already used by other user. Please register with other email by clicking on Back button.');
845
- $this->mo_auth_show_error_message();
846
- }*/
847
  }
848
 
849
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_send_query" ) { //Help me or support
850
- $query = '';
851
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['EMAIL_MANDATORY'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['query'] ) ) {
852
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "EMAIL_MANDATORY" ) );
853
- $this->mo_auth_show_error_message();
 
854
 
855
- return;
856
  } else {
857
- $query = sanitize_text_field( $_POST['query'] );
858
- $email = sanitize_text_field( $_POST['EMAIL_MANDATORY'] );
859
- $phone = sanitize_text_field( $_POST['query_phone'] );
860
- $contact_us = new Customer_Setup();
861
- $submited = json_decode( $contact_us->submit_contact_us( $email, $phone, $query ), true );
862
- if ( json_last_error() == JSON_ERROR_NONE ) {
863
- if ( is_array( $submited ) && array_key_exists( 'status', $submited ) && $submited['status'] == 'ERROR' ) {
864
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $submited['message'] ) );
865
- $this->mo_auth_show_error_message();
866
- } else {
867
- if ( $submited == false ) {
868
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SUBMITTING_QUERY" ) );
 
 
 
 
869
  $this->mo_auth_show_error_message();
870
  } else {
871
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "QUERY_SUBMITTED_SUCCESSFULLY" ) );
872
- $this->mo_auth_show_success_message();
 
 
 
 
 
873
  }
874
  }
875
- }
876
 
 
877
  }
878
  }
879
 
@@ -886,49 +993,59 @@ class Miniorange_Authentication {
886
  }
887
 
888
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo_auth_login_settings_save' ) {
889
- $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID );
890
- if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
 
 
 
 
 
 
 
 
891
 
892
- update_option( 'mo2f_login_option', isset( $_POST['mo2f_login_option'] ) ? $_POST['mo2f_login_option'] : 0 );
893
- update_option( 'mo2f_remember_device', isset( $_POST['mo2f_remember_device'] ) ? $_POST['mo2f_remember_device'] : 0 );
894
- if ( get_option( 'mo2f_login_option' ) == 0 ) {
895
 
896
- update_option( 'mo2f_remember_device', 0 );
897
- }
898
- update_option( 'mo2f_enable_forgotphone', isset( $_POST['mo2f_forgotphone'] ) ? $_POST['mo2f_forgotphone'] : 0 );
899
- update_option( 'mo2f_enable_login_with_2nd_factor', isset( $_POST['mo2f_login_with_username_and_2factor'] ) ? $_POST['mo2f_login_with_username_and_2factor'] : 0 );
900
- update_option( 'mo2f_enable_xmlrpc', isset( $_POST['mo2f_enable_xmlrpc'] ) ? $_POST['mo2f_enable_xmlrpc'] : 0 );
901
 
902
 
903
- if ( get_option( 'mo2f_remember_device' ) && ! get_option( 'mo2f_app_secret' ) ) {
904
- $get_app_secret = new Miniorange_Rba_Attributes();
905
- $rba_response = json_decode( $get_app_secret->mo2f_get_app_secret(), true ); //fetch app secret
906
- if ( json_last_error() == JSON_ERROR_NONE ) {
907
- if ( $rba_response['status'] == 'SUCCESS' ) {
908
- update_option( 'mo2f_app_secret', $rba_response['appSecret'] );
 
 
 
 
 
909
  } else {
910
  update_option( 'mo2f_remember_device', 0 );
911
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_SETTINGS" ) );
912
  $this->mo_auth_show_error_message();
913
  }
914
- } else {
915
- update_option( 'mo2f_remember_device', 0 );
916
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_SETTINGS" ) );
917
- $this->mo_auth_show_error_message();
918
  }
919
- }
920
 
921
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "SETTINGS_SAVED" ) );
922
- $this->mo_auth_show_success_message();
923
 
924
- } else {
925
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQUEST" ) );
926
- $this->mo_auth_show_error_message();
 
927
  }
928
  }
929
 
930
 
931
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_sync_sms_transactions" ) {
 
932
  $customer = new Customer_Setup();
933
  $content = json_decode( $customer->get_customer_transactions( get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
934
  if ( ! array_key_exists( 'smsRemaining', $content ) ) {
@@ -947,199 +1064,278 @@ class Miniorange_Authentication {
947
 
948
  }
949
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
950
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_skip_feedback' ) {
951
 
952
  //update_option( 'mo2f_feedback_form', 1 );
953
- deactivate_plugins( '/miniorange-2-factor-authentication/miniorange_2_factor_settings.php' );
 
 
 
 
 
 
 
 
 
954
 
955
  }
956
  if ( isset( $_POST['mo2f_feedback'] ) and $_POST['mo2f_feedback'] == 'mo2f_feedback' ) {
 
 
 
 
 
 
 
 
 
 
957
 
958
- $reasons_not_to_worry_about = array( "Upgrading to Premium", "Temporary deactivation - Testing" );
959
-
960
- $message = 'Plugin Deactivated:';
961
 
962
- if ( isset( $_POST['deactivate_plugin'] ) ) {
963
- if ( $_POST['query_feedback'] == '' and $_POST['deactivate_plugin'] == 'Other Reasons:' ) {
964
- // feedback add
965
- update_option( 'mo2f_message', 'Please let us know the reason for deactivation so that we improve the user experience.' );
966
- } else {
967
 
968
- if ( ! in_array( $_POST['deactivate_plugin'], $reasons_not_to_worry_about ) ) {
969
 
970
- $message .= $_POST['deactivate_plugin'];
971
 
972
- if ( $_POST['query_feedback'] != '' ) {
973
- $message .= ':' . $_POST['query_feedback'];
974
- }
975
 
976
 
977
- if($_POST['deactivate_plugin'] == "Conflicts with other plugins"){
978
- $plugin_selected = $_POST['plugin_selected'];
979
- $plugin = MO2f_Utility::get_plugin_name_by_identifier($plugin_selected);
980
 
981
- $message .= ", Plugin selected - " . $plugin . ".";
982
- }
983
 
984
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
985
- if ( $email == '' ) {
986
- $email = $user->user_email;
987
- }
988
 
989
- $phone = $Mo2fdbQueries->get_user_detail( 'mo2f_user_phone', $user->ID );;
990
 
991
- $contact_us = new Customer_Setup();
992
- $submited = json_decode( $contact_us->send_email_alert( $email, $phone, $message ), true );
993
 
994
- if ( json_last_error() == JSON_ERROR_NONE ) {
995
- if ( is_array( $submited ) && array_key_exists( 'status', $submited ) && $submited['status'] == 'ERROR' ) {
996
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $submited['message'] ) );
997
- $this->mo_auth_show_error_message();
998
- } else {
999
- if ( $submited == false ) {
1000
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SUBMITTING_QUERY" ) );
1001
  $this->mo_auth_show_error_message();
1002
  } else {
1003
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "QUERY_SUBMITTED_SUCCESSFULLY" ) );
1004
- $this->mo_auth_show_success_message();
1005
- //update_option( 'mo2f_feedback_form', 1 );
 
 
 
 
 
1006
  }
1007
  }
1008
  }
1009
- }
1010
 
1011
- //update_option( 'mo2f_feedback_form', 1 );
1012
- deactivate_plugins( '/miniorange-2-factor-authentication/miniorange_2_factor_settings.php' );
1013
 
1014
- }
1015
 
1016
- } else {
1017
- update_option( 'mo2f_message', 'Please Select one of the reasons if your reason isnot mention please select Other Reasons' );
1018
 
 
1019
  }
1020
 
1021
  }
1022
 
1023
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_resend_user_otp" ) { //resend OTP over email for additional admin and non-admin user
1024
- $customer = new Customer_Setup();
1025
- $content = json_decode( $customer->send_otp_token( get_user_meta( $user->ID, 'user_email', true ), 'EMAIL', get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1026
- if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) {
1027
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "OTP_SENT" ) . ' <b>' . ( get_user_meta( $user->ID, 'user_email', true ) ) . '</b>. ' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
1028
- update_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account', $content['txId'] );
1029
- $mo_2factor_user_registration_status = 'MO_2_FACTOR_OTP_DELIVERED_SUCCESS';
1030
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
1031
- $this->mo_auth_show_success_message();
1032
- } else {
1033
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_EMAIL" ) );
1034
- $mo_2factor_user_registration_status = 'MO_2_FACTOR_OTP_DELIVERED_FAILURE';
1035
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
1036
- $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
 
1037
 
1038
- }
 
1039
 
1040
  }
1041
 
1042
  if ( isset( $_POST['option'] ) and ( $_POST['option'] == "mo2f_configure_miniorange_authenticator_validate" || $_POST['option'] == 'mo_auth_mobile_reconfiguration_complete' ) ) { //mobile registration successfully complete for all users
1043
 
1044
- delete_option( 'mo2f_transactionId' );
1045
- $session_variables = array( 'mo2f_qrCode', 'mo2f_transactionId', 'mo2f_show_qr_code' );
1046
- MO2f_Utility::unset_session_variables( $session_variables );
 
 
1047
 
1048
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1049
- $TwoFA_method_to_configure = get_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', true );
1050
- $enduser = new Two_Factor_Setup();
1051
- $current_method = MO2f_Utility::mo2f_decode_2_factor( $TwoFA_method_to_configure, "server" );
 
1052
 
1053
- $response = json_decode( $enduser->mo2f_update_userinfo( $email, $current_method, null, null, null ), true );
 
 
 
1054
 
1055
- if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate Qr code */
1056
- if ( $response['status'] == 'ERROR' ) {
1057
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1058
 
1059
- $this->mo_auth_show_error_message();
 
 
1060
 
 
1061
 
1062
- } else if ( $response['status'] == 'SUCCESS' ) {
1063
 
1064
- $selectedMethod = $TwoFA_method_to_configure;
1065
 
1066
- delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
1067
 
 
1068
 
1069
- $Mo2fdbQueries->update_user_details( $user->ID, array(
1070
- 'mo2f_configured_2FA_method' => $selectedMethod,
1071
- 'mobile_registration_status' => true,
1072
- 'mo2f_miniOrangeQRCodeAuthentication_config_status' => true,
1073
- 'mo2f_miniOrangeSoftToken_config_status' => true,
1074
- 'mo2f_miniOrangePushNotification_config_status' => true,
1075
- 'user_registration_with_miniorange' => 'SUCCESS',
1076
- 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS'
1077
- ) );
1078
 
1079
- $is_nc_with_unlimited_users = get_option( 'mo2f_is_NC' ) && ! get_option( 'mo2f_is_NNC' );
 
 
 
 
 
 
 
 
1080
 
1081
- if ( ! $is_nc_with_unlimited_users && $selectedMethod == 'miniOrange Soft Token' ) {
1082
- update_option( 'mo2f_enable_2fa_prompt_on_login_page', 1 );
1083
- }
1084
 
1085
- delete_user_meta( $user->ID, 'configure_2FA' );
1086
- mo2f_display_test_2fa_notification($user);
1087
 
1088
- } else {
1089
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1090
- $this->mo_auth_show_error_message();
1091
 
1092
- }
 
 
1093
 
1094
- } else {
1095
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1096
- $this->mo_auth_show_error_message();
1097
- }
 
 
 
1098
 
1099
  }
1100
 
1101
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_mobile_authenticate_success' ) { // mobile registration for all users(common)
1102
- if ( current_user_can( 'manage_options' ) ) {
1103
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1104
- } else {
1105
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1106
- }
1107
 
1108
- $session_variables = array( 'mo2f_qrCode', 'mo2f_transactionId', 'mo2f_show_qr_code' );
1109
- MO2f_Utility::unset_session_variables( $session_variables );
 
 
 
1110
 
1111
- delete_user_meta( $user->ID, 'test_2FA' );
1112
- $this->mo_auth_show_success_message();
 
 
 
 
 
 
1113
 
 
 
 
 
 
 
1114
  }
1115
 
1116
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_mobile_authenticate_error' ) { //mobile registration failed for all users(common)
1117
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "AUTHENTICATION_FAILED" ) );
1118
- MO2f_Utility::unset_session_variables( 'mo2f_show_qr_code' );
1119
- $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
 
1120
 
1121
  }
1122
 
1123
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_setting_configuration" ) // redirect to setings page
1124
- {
 
1125
  $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS' ) );
1126
 
1127
  }
1128
 
1129
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_refresh_mobile_qrcode" ) { // refrsh Qrcode for all users
 
 
 
 
 
 
1130
 
1131
- $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID );
1132
- if ( in_array( $mo_2factor_user_registration_status, array(
1133
- 'MO_2_FACTOR_INITIALIZE_TWO_FACTOR',
1134
- 'MO_2_FACTOR_INITIALIZE_MOBILE_REGISTRATION',
1135
- 'MO_2_FACTOR_PLUGIN_SETTINGS'
1136
- ) ) ) {
1137
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1138
- $this->mo2f_get_qr_code_for_mobile( $email, $user->ID );
1139
  } else {
1140
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "REGISTER_WITH_MO" ) );
1141
- $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
 
1142
 
 
1143
  }
1144
  }
1145
 
@@ -1219,369 +1415,481 @@ class Miniorange_Authentication {
1219
 
1220
 
1221
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo_2factor_backto_user_registration' ) { //back to registration page for additional admin and non-admin
1222
- delete_user_meta( $user->ID, 'user_email' );
1223
- $Mo2fdbQueries->delete_user_details( $user->ID );
1224
- MO2f_Utility::unset_session_variables( 'mo2f_transactionId' );
1225
- delete_option( 'mo2f_transactionId' );
 
1226
 
 
 
 
 
 
 
 
1227
 
1228
  }
1229
 
1230
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_soft_token' ) { // validate Soft Token during test for all users
1231
- $otp_token = '';
1232
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
1233
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ENTER_VALUE" ) );
1234
- $this->mo_auth_show_error_message();
 
 
 
1235
 
1236
- return;
1237
  } else {
1238
- $otp_token = sanitize_text_field( $_POST['otp_token'] );
1239
- }
1240
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1241
- $customer = new Customer_Setup();
1242
- $content = json_decode( $customer->validate_otp_token( 'SOFT TOKEN', $email, null, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1243
- if ( $content['status'] == 'ERROR' ) {
1244
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $content['message'] ) );
1245
- $this->mo_auth_show_error_message();
1246
- } else {
1247
- if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated and generate QRCode
1248
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1249
 
1250
- delete_user_meta( $user->ID, 'test_2FA' );
1251
- $this->mo_auth_show_success_message();
 
 
 
 
 
 
 
 
 
 
 
1252
 
 
 
1253
 
1254
- } else { // OTP Validation failed.
1255
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
1256
- $this->mo_auth_show_error_message();
1257
 
 
 
 
 
 
1258
  }
1259
  }
1260
  }
1261
 
1262
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_otp_over_sms' ) { //validate otp over sms and phone call during test for all users
1263
- $otp_token = '';
1264
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
1265
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ENTER_VALUE" ) );
1266
- $this->mo_auth_show_error_message();
 
 
1267
 
1268
- return;
1269
  } else {
1270
- $otp_token = sanitize_text_field( $_POST['otp_token'] );
1271
- }
 
 
1272
 
1273
- //if the php session folder has insufficient permissions, temporary options to be used
1274
- $mo2f_transactionId = isset( $_SESSION['mo2f_transactionId'] ) && ! empty( $_SESSION['mo2f_transactionId'] ) ? $_SESSION['mo2f_transactionId'] : get_option( 'mo2f_transactionId' );
1275
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1276
- $selected_2_2factor_method = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1277
- $customer = new Customer_Setup();
1278
- $content = json_decode( $customer->validate_otp_token( get_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', true ), $email, $mo2f_transactionId, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1279
 
1280
- if ( $content['status'] == 'ERROR' ) {
1281
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $content['message'] ) );
1282
- $this->mo_auth_show_error_message();
1283
- } else {
1284
- if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated
1285
- if ( current_user_can( 'manage_options' ) ) {
1286
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1287
  } else {
1288
- update_option( 'mo2f_message', Mo2fConstants::langTranslate( "COMPLETED_TEST" ) );
 
1289
  }
1290
 
1291
- delete_user_meta( $user->ID, 'test_2FA' );
1292
- $this->mo_auth_show_success_message();
1293
-
1294
- } else {
1295
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
1296
- $this->mo_auth_show_error_message();
1297
  }
1298
-
1299
  }
1300
  }
1301
 
1302
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_out_of_band_success' ) {
 
 
 
 
 
1303
 
1304
- $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
1305
- $mo2f_EmailVerification_config_status = $Mo2fdbQueries->get_user_detail( 'mo2f_EmailVerification_config_status', $user->ID );
1306
- if ( ! current_user_can( 'manage_options' ) && $mo2f_configured_2FA_method == 'OUT OF BAND EMAIL' ) {
1307
- if ( $mo2f_EmailVerification_config_status ) {
1308
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
 
 
 
 
 
 
 
 
1309
  } else {
1310
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1311
- $enduser = new Two_Factor_Setup();
1312
- $response = json_decode( $enduser->mo2f_update_userinfo( $email, $mo2f_configured_2FA_method, null, null, null ), true );
1313
- update_option( 'mo2f_message', '<b> ' . Mo2fConstants:: langTranslate( "EMAIL_VERFI" ) . '</b> ' . Mo2fConstants:: langTranslate( "SET_AS_2ND_FACTOR" ) );
1314
  }
1315
- } else {
1316
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1317
- }
1318
- delete_user_meta( $user->ID, 'test_2FA' );
1319
- $Mo2fdbQueries->update_user_details( $user->ID, array(
1320
- 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS',
1321
- 'mo2f_EmailVerification_config_status' => true
1322
- ) );
1323
 
1324
- $this->mo_auth_show_success_message();
 
1325
 
1326
 
1327
  }
1328
 
1329
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_out_of_band_error' ) { //push and out of band email denied
1330
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "DENIED_REQUEST" ) );
1331
- delete_user_meta( $user->ID, 'test_2FA' );
1332
- $Mo2fdbQueries->update_user_details( $user->ID, array(
1333
- 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS',
1334
- 'mo2f_EmailVerification_config_status' => true
1335
- ) );
1336
- $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
 
1337
 
1338
  }
1339
 
1340
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_google_authy_test' ) {
 
 
 
 
 
 
1341
 
1342
- $otp_token = '';
1343
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
1344
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ENTER_VALUE" ) );
1345
- $this->mo_auth_show_error_message();
1346
-
1347
- return;
1348
  } else {
1349
- $otp_token = sanitize_text_field( $_POST['otp_token'] );
1350
- }
1351
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1352
- $customer = new Customer_Setup();
1353
- $content = json_decode( $customer->validate_otp_token( 'GOOGLE AUTHENTICATOR', $email, null, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1354
- if ( json_last_error() == JSON_ERROR_NONE ) {
 
 
 
 
 
 
 
1355
 
1356
- if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //Google OTP validated
1357
 
1358
- if ( current_user_can( 'manage_options' ) ) {
1359
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1360
- } else {
1361
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1362
- }
1363
 
1364
- delete_user_meta( $user->ID, 'test_2FA' );
1365
- $this->mo_auth_show_success_message();
1366
 
1367
 
1368
- } else { // OTP Validation failed.
1369
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
 
 
 
 
 
1370
  $this->mo_auth_show_error_message();
1371
 
1372
  }
1373
- } else {
1374
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_VALIDATING_OTP" ) );
1375
- $this->mo_auth_show_error_message();
1376
-
1377
  }
1378
  }
1379
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1380
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_google_authenticator_validate' ) {
1381
- $otpToken = $_POST['google_token'];
1382
- $ga_secret = isset( $_POST['google_auth_secret'] ) ? $_POST['google_auth_secret'] : null;
1383
- if ( MO2f_Utility::mo2f_check_number_length( $otpToken ) ) {
1384
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1385
- $google_auth = new Miniorange_Rba_Attributes();
1386
- $google_response = json_decode( $google_auth->mo2f_validate_google_auth( $email, $otpToken, $ga_secret ), true );
1387
- if ( json_last_error() == JSON_ERROR_NONE ) {
1388
- if ( $google_response['status'] == 'SUCCESS' ) {
1389
- $enduser = new Two_Factor_Setup();
1390
- $response = json_decode( $enduser->mo2f_update_userinfo( $email, "GOOGLE AUTHENTICATOR", null, null, null ), true );
 
 
 
 
 
 
 
 
1391
 
1392
 
1393
- if ( json_last_error() == JSON_ERROR_NONE ) {
1394
 
1395
- if ( $response['status'] == 'SUCCESS' ) {
1396
 
1397
- delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
1398
 
1399
- delete_user_meta( $user->ID, 'configure_2FA' );
1400
 
1401
- $Mo2fdbQueries->update_user_details( $user->ID, array(
1402
- 'mo2f_GoogleAuthenticator_config_status' => true,
1403
- 'mo2f_AuthyAuthenticator_config_status' => false,
1404
- 'mo2f_configured_2FA_method' => "Google Authenticator",
1405
- 'user_registration_with_miniorange' => 'SUCCESS',
1406
- 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS'
1407
- ) );
1408
 
1409
- update_user_meta( $user->ID, 'mo2f_external_app_type', "Google Authenticator" );
1410
- mo2f_display_test_2fa_notification($user);
1411
 
 
 
 
 
 
1412
  } else {
1413
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1414
  $this->mo_auth_show_error_message();
1415
 
1416
  }
1417
  } else {
1418
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1419
  $this->mo_auth_show_error_message();
1420
 
1421
  }
1422
  } else {
1423
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_OTP_CAUSES" ) . '<br>1. ' . Mo2fConstants:: langTranslate( "INVALID_OTP" ) . '<br>2. ' . Mo2fConstants:: langTranslate( "APP_TIME_SYNC" ) );
1424
  $this->mo_auth_show_error_message();
1425
 
1426
  }
1427
  } else {
1428
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_VALIDATING_USER" ) );
1429
  $this->mo_auth_show_error_message();
1430
 
1431
  }
1432
- } else {
1433
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ONLY_DIGITS_ALLOWED" ) );
1434
- $this->mo_auth_show_error_message();
1435
-
1436
  }
1437
  }
1438
 
1439
 
1440
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_authy_authenticator' ) {
1441
- $authy = new Miniorange_Rba_Attributes();
1442
- $user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1443
- $authy_response = json_decode( $authy->mo2f_google_auth_service( $user_email ), true );
1444
- if ( json_last_error() == JSON_ERROR_NONE ) {
1445
- if ( $authy_response['status'] == 'SUCCESS' ) {
1446
- $mo2f_authy_keys = array();
1447
- $mo2f_authy_keys['authy_qrCode'] = $authy_response['qrCodeData'];
1448
- $mo2f_authy_keys['mo2f_authy_secret'] = $authy_response['secret'];
1449
- $_SESSION['mo2f_authy_keys'] = $mo2f_authy_keys;
 
 
 
 
 
 
 
 
 
 
 
 
1450
  } else {
1451
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_USER_REGISTRATION" ) );
1452
  $this->mo_auth_show_error_message();
1453
  }
1454
- } else {
1455
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_USER_REGISTRATION" ) );
1456
- $this->mo_auth_show_error_message();
1457
  }
1458
  }
1459
 
1460
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_authy_authenticator_validate' ) {
1461
- $otpToken = $_POST['mo2f_authy_token'];
1462
- $authy_secret = isset( $_POST['mo2f_authy_secret'] ) ? $_POST['mo2f_authy_secret'] : null;
1463
- if ( MO2f_Utility::mo2f_check_number_length( $otpToken ) ) {
1464
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1465
- $authy_auth = new Miniorange_Rba_Attributes();
1466
- $authy_response = json_decode( $authy_auth->mo2f_validate_google_auth( $email, $otpToken, $authy_secret ), true );
1467
- if ( json_last_error() == JSON_ERROR_NONE ) {
1468
- if ( $authy_response['status'] == 'SUCCESS' ) {
1469
- $enduser = new Two_Factor_Setup();
1470
- $response = json_decode( $enduser->mo2f_update_userinfo( $email, 'GOOGLE AUTHENTICATOR', null, null, null ), true );
1471
- if ( json_last_error() == JSON_ERROR_NONE ) {
 
 
 
 
 
 
 
 
1472
 
1473
- if ( $response['status'] == 'SUCCESS' ) {
1474
- $Mo2fdbQueries->update_user_details( $user->ID, array(
1475
- 'mo2f_GoogleAuthenticator_config_status' => false,
1476
- 'mo2f_AuthyAuthenticator_config_status' => true,
1477
- 'mo2f_configured_2FA_method' => "Authy Authenticator",
1478
- 'user_registration_with_miniorange' => 'SUCCESS',
1479
- 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS'
1480
- ) );
1481
- update_user_meta( $user->ID, 'mo2f_external_app_type', "Authy Authenticator" );
1482
- delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
1483
- delete_user_meta( $user->ID, 'configure_2FA' );
1484
- update_option( 'mo2f_enable_2fa_prompt_on_login_page', 1 );
1485
- mo2f_display_test_2fa_notification($user);
1486
 
 
 
 
 
1487
  } else {
1488
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1489
  $this->mo_auth_show_error_message();
1490
  }
1491
  } else {
1492
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1493
  $this->mo_auth_show_error_message();
1494
  }
1495
  } else {
1496
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_OTP_CAUSES" ) . '<br>1. ' . Mo2fConstants:: langTranslate( "INVALID_OTP" ) . '<br>2. ' . Mo2fConstants:: langTranslate( "APP_TIME_SYNC" ) );
1497
  $this->mo_auth_show_error_message();
1498
  }
1499
  } else {
1500
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_VALIDATING_USER" ) );
1501
  $this->mo_auth_show_error_message();
1502
  }
1503
- } else {
1504
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ONLY_DIGITS_ALLOWED" ) );
1505
- $this->mo_auth_show_error_message();
1506
  }
1507
  }
1508
 
1509
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_kba' ) {
1510
-
1511
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kbaquestion_1'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kba_ans1'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kbaquestion_2'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kba_ans2'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kbaquestion_3'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kba_ans3'] ) ) {
1512
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1513
- $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
 
1514
 
1515
 
1516
- return;
1517
- }
1518
 
1519
- $kba_q1 = $_POST['mo2f_kbaquestion_1'];
1520
- $kba_a1 = sanitize_text_field( $_POST['mo2f_kba_ans1'] );
1521
- $kba_q2 = $_POST['mo2f_kbaquestion_2'];
1522
- $kba_a2 = sanitize_text_field( $_POST['mo2f_kba_ans2'] );
1523
- $kba_q3 = sanitize_text_field( $_POST['mo2f_kbaquestion_3'] );
1524
- $kba_a3 = sanitize_text_field( $_POST['mo2f_kba_ans3'] );
1525
 
1526
 
1527
- if ( strcasecmp( $kba_q1, $kba_q2 ) == 0 || strcasecmp( $kba_q2, $kba_q3 ) == 0 || strcasecmp( $kba_q3, $kba_q1 ) == 0 ) {
1528
- update_option( 'mo2f_message', 'The questions you select must be unique.' );
1529
- $this->mo_auth_show_error_message();
1530
 
1531
 
1532
- return;
1533
- }
1534
- $kba_q1 = addcslashes( stripslashes( $kba_q1 ), '"\\' );
1535
- $kba_a1 = addcslashes( stripslashes( $kba_a1 ), '"\\' );
1536
- $kba_q2 = addcslashes( stripslashes( $kba_q2 ), '"\\' );
1537
- $kba_a2 = addcslashes( stripslashes( $kba_a2 ), '"\\' );
1538
- $kba_q3 = addcslashes( stripslashes( $kba_q3 ), '"\\' );
1539
- $kba_a3 = addcslashes( stripslashes( $kba_a3 ), '"\\' );
 
 
 
 
 
 
 
 
1540
 
1541
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1542
- $kba_registration = new Two_Factor_Setup();
1543
- $kba_reg_reponse = json_decode( $kba_registration->register_kba_details( $email, $kba_q1, $kba_a1, $kba_q2, $kba_a2, $kba_q3, $kba_a3 ), true );
1544
- if ( json_last_error() == JSON_ERROR_NONE ) {
1545
- if ( $kba_reg_reponse['status'] == 'SUCCESS' ) {
1546
- if ( isset( $_POST['mobile_kba_option'] ) && $_POST['mobile_kba_option'] == 'mo2f_request_for_kba_as_emailbackup' ) {
1547
- MO2f_Utility::unset_session_variables( 'mo2f_mobile_support' );
1548
 
1549
- delete_user_meta( $user->ID, 'configure_2FA' );
1550
- delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
 
1551
 
1552
- $message = mo2f_lt( 'Your KBA as alternate 2 factor is configured successfully.' );
1553
- update_option( 'mo2f_message', $message );
1554
- $this->mo_auth_show_success_message();
 
 
 
 
1555
 
1556
- } else {
1557
- $enduser = new Two_Factor_Setup();
1558
- $response = json_decode( $enduser->mo2f_update_userinfo( $email, 'KBA', null, null, null ), true );
1559
- if ( json_last_error() == JSON_ERROR_NONE ) {
1560
- if ( $response['status'] == 'ERROR' ) {
1561
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1562
- $this->mo_auth_show_error_message();
1563
 
1564
- } else if ( $response['status'] == 'SUCCESS' ) {
1565
- delete_user_meta( $user->ID, 'configure_2FA' );
 
 
 
1566
 
1567
- $Mo2fdbQueries->update_user_details( $user->ID, array(
1568
- 'mo2f_SecurityQuestions_config_status' => true,
1569
- 'mo2f_configured_2FA_method' => "Security Questions",
1570
- 'mo_2factor_user_registration_status' => "MO_2_FACTOR_PLUGIN_SETTINGS"
1571
- ) );
1572
 
1573
- mo2f_display_test_2fa_notification($user);
 
 
1574
 
 
1575
  } else {
1576
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1577
  $this->mo_auth_show_error_message();
1578
 
1579
  }
1580
- } else {
1581
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1582
- $this->mo_auth_show_error_message();
1583
-
1584
  }
 
 
 
 
 
 
1585
  }
1586
  } else {
1587
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_KBA" ) );
@@ -1590,178 +1898,201 @@ class Miniorange_Authentication {
1590
 
1591
  return;
1592
  }
1593
- } else {
1594
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_KBA" ) );
1595
- $this->mo_auth_show_error_message();
1596
-
1597
-
1598
- return;
1599
  }
1600
 
1601
  }
1602
 
1603
 
1604
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_kba_details' ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1605
 
1606
- $kba_ans_1 = '';
1607
- $kba_ans_2 = '';
1608
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_answer_1'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_answer_1'] ) ) {
1609
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1610
- $this->mo_auth_show_error_message();
1611
-
1612
- return;
1613
- } else {
1614
- $kba_ans_1 = sanitize_text_field( $_POST['mo2f_answer_1'] );
1615
- $kba_ans_2 = sanitize_text_field( $_POST['mo2f_answer_2'] );
1616
- }
1617
 
1618
- //if the php session folder has insufficient permissions, temporary options to be used
1619
- $kba_questions = isset( $_SESSION['mo_2_factor_kba_questions'] ) && ! empty( $_SESSION['mo_2_factor_kba_questions'] ) ? $_SESSION['mo_2_factor_kba_questions'] : get_option( 'kba_questions' );
1620
 
1621
- $kbaAns = array();
1622
- $kbaAns[0] = $kba_questions[0];
1623
- $kbaAns[1] = $kba_ans_1;
1624
- $kbaAns[2] = $kba_questions[1];
1625
- $kbaAns[3] = $kba_ans_2;
1626
 
1627
- //if the php session folder has insufficient permissions, temporary options to be used
1628
- $mo2f_transactionId = isset( $_SESSION['mo2f_transactionId'] ) && ! empty( $_SESSION['mo2f_transactionId'] ) ? $_SESSION['mo2f_transactionId'] : get_option( 'mo2f_transactionId' );
1629
 
1630
- $kba_validate = new Customer_Setup();
1631
- $kba_validate_response = json_decode( $kba_validate->validate_otp_token( 'KBA', null, $mo2f_transactionId, $kbaAns, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1632
 
1633
- if ( json_last_error() == JSON_ERROR_NONE ) {
1634
- if ( strcasecmp( $kba_validate_response['status'], 'SUCCESS' ) == 0 ) {
1635
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1636
- delete_user_meta( $user->ID, 'test_2FA' );
1637
- $this->mo_auth_show_success_message();
1638
 
1639
- } else { // KBA Validation failed.
1640
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ANSWERS" ) );
1641
- $this->mo_auth_show_error_message();
1642
 
 
1643
  }
1644
  }
1645
  }
1646
 
1647
 
1648
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_otp_over_sms_send_otp' ) { // sendin otp for configuring OTP over SMS
1649
- $phone = sanitize_text_field( $_POST['verify_phone'] );
 
 
 
 
 
1650
 
1651
- if ( MO2f_Utility::mo2f_check_empty_or_null( $phone ) ) {
1652
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1653
- $this->mo_auth_show_error_message();
1654
 
1655
- return;
1656
- }
 
 
 
 
1657
 
1658
- $phone = str_replace( ' ', '', $phone );
1659
- $_SESSION['user_phone'] = $phone;
1660
- update_option( 'user_phone_temp', $phone );
1661
- $customer = new Customer_Setup();
1662
- $currentMethod = "SMS";
1663
 
1664
- $content = json_decode( $customer->send_otp_token( $phone, $currentMethod, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1665
 
1666
- if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate otp token */
1667
- if ( $content['status'] == 'ERROR' ) {
1668
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1669
- $this->mo_auth_show_error_message();
1670
- } else if ( $content['status'] == 'SUCCESS' ) {
1671
- $_SESSION['mo2f_transactionId'] = $content['txId'];
1672
- update_option( 'mo2f_transactionId', $content['txId'] );
1673
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "OTP_SENT" ) . ' ' . $phone . ' .' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
1674
- update_option( 'mo2f_number_of_transactions', get_option( 'mo2f_number_of_transactions' ) - 1 );
1675
- $this->mo_auth_show_success_message();
1676
  } else {
1677
- update_option( 'mo2f_message', Mo2fConstants::langTranslate( $content['message'] ) );
1678
  $this->mo_auth_show_error_message();
1679
  }
1680
-
1681
- } else {
1682
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1683
- $this->mo_auth_show_error_message();
1684
  }
1685
  }
1686
 
1687
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_otp_over_sms_validate' ) {
1688
- $otp_token = '';
1689
- if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
1690
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1691
- $this->mo_auth_show_error_message();
 
1692
 
1693
- return;
1694
- } else {
1695
- $otp_token = sanitize_text_field( $_POST['otp_token'] );
1696
- }
 
 
 
 
 
 
 
1697
 
1698
- //if the php session folder has insufficient permissions, temporary options to be used
1699
- $mo2f_transactionId = isset( $_SESSION['mo2f_transactionId'] ) && ! empty( $_SESSION['mo2f_transactionId'] ) ? $_SESSION['mo2f_transactionId'] : get_option( 'mo2f_transactionId' );
1700
- $user_phone = isset( $_SESSION['user_phone'] ) && $_SESSION['user_phone'] != 'false' ? $_SESSION['user_phone'] : get_option( 'user_phone_temp' );
1701
- $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
1702
- $phone = $Mo2fdbQueries->get_user_detail( 'mo2f_user_phone', $user->ID );
1703
- $customer = new Customer_Setup();
1704
- $content = json_decode( $customer->validate_otp_token( $mo2f_configured_2FA_method, null, $mo2f_transactionId, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1705
 
1706
- if ( $content['status'] == 'ERROR' ) {
1707
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $content['message'] ) );
1708
 
1709
- } else if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated
1710
- if ( $phone && strlen( $phone ) >= 4 ) {
1711
- if ( $user_phone != $phone ) {
1712
- $Mo2fdbQueries->update_user_details( $user->ID, array( 'mobile_registration_status' => false ) );
1713
 
 
1714
  }
1715
- }
1716
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1717
 
1718
- $enduser = new Two_Factor_Setup();
1719
- $TwoFA_method_to_configure = get_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', true );
1720
- $current_method = MO2f_Utility::mo2f_decode_2_factor( $TwoFA_method_to_configure, "server" );
1721
- $response = json_decode( $enduser->mo2f_update_userinfo( $email, $current_method, $user_phone, null, null ), true );
1722
 
1723
- if ( json_last_error() == JSON_ERROR_NONE ) {
1724
 
1725
- if ( $response['status'] == 'ERROR' ) {
1726
- MO2f_Utility::unset_session_variables( 'user_phone' );
1727
- delete_option( 'user_phone_temp' );
1728
 
1729
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1730
- $this->mo_auth_show_error_message();
1731
- } else if ( $response['status'] == 'SUCCESS' ) {
1732
-
1733
- $Mo2fdbQueries->update_user_details( $user->ID, array(
1734
- 'mo2f_configured_2FA_method' => 'OTP Over SMS',
1735
- 'mo2f_OTPOverSMS_config_status' => true,
1736
- 'user_registration_with_miniorange' => 'SUCCESS',
1737
- 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS',
1738
- 'mo2f_user_phone' => $user_phone
1739
- ) );
1740
 
1741
- delete_user_meta( $user->ID, 'configure_2FA' );
1742
- delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
1743
 
1744
- unset( $_SESSION['user_phone'] );
1745
- MO2f_Utility::unset_session_variables( 'user_phone' );
1746
- delete_option( 'user_phone_temp' );
1747
 
1748
- mo2f_display_test_2fa_notification($user);
 
 
 
 
 
 
1749
  } else {
1750
  MO2f_Utility::unset_session_variables( 'user_phone' );
1751
  delete_option( 'user_phone_temp' );
1752
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1753
  $this->mo_auth_show_error_message();
1754
  }
1755
- } else {
1756
- MO2f_Utility::unset_session_variables( 'user_phone' );
1757
- delete_option( 'user_phone_temp' );
1758
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1759
  $this->mo_auth_show_error_message();
1760
  }
1761
-
1762
- } else { // OTP Validation failed.
1763
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
1764
- $this->mo_auth_show_error_message();
1765
  }
1766
 
1767
  }
@@ -1769,6 +2100,15 @@ class Miniorange_Authentication {
1769
  // user clicks on Set 2-Factor method
1770
  if ( ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_free_plan_auth_methods' ) ||
1771
  ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_standard_plan_auth_methods' ) ) {
 
 
 
 
 
 
 
 
 
1772
  $is_customer_registered = $Mo2fdbQueries->get_user_detail( 'user_registration_with_miniorange', $user->ID ) == 'SUCCESS' ? true : false;
1773
 
1774
  $selected_2FA_method = MO2f_Utility::mo2f_decode_2_factor( isset( $_POST['mo2f_configured_2FA_method_free_plan'] ) ? $_POST['mo2f_configured_2FA_method_free_plan'] : $_POST['mo2f_selected_action_standard_plan'], "wpdb" );
@@ -1802,7 +2142,7 @@ class Miniorange_Authentication {
1802
  "miniOrange Soft Token",
1803
  "Authy Authenticator"
1804
  ) ) ) {
1805
- update_option( 'mo2f_enable_2fa_prompt_on_login_page', 1 );
1806
  } else {
1807
  update_option( 'mo2f_enable_2fa_prompt_on_login_page', 0 );
1808
  }
@@ -1825,173 +2165,227 @@ class Miniorange_Authentication {
1825
 
1826
  display_customer_registration_forms( $user );
1827
  }
 
1828
  }
1829
 
1830
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_enable_2FA_for_users_option' ) {
1831
- update_option( 'mo2f_enable_2fa_for_users', isset( $_POST['mo2f_enable_2fa_for_users'] ) ? $_POST['mo2f_enable_2fa_for_users'] : 0 );
 
 
 
 
 
 
 
 
 
1832
  }
1833
 
1834
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_disable_proxy_setup_option' ) {
1835
-
1836
- delete_option( 'mo2f_proxy_host' );
1837
- delete_option( 'mo2f_port_number' );
1838
- delete_option( 'mo2f_proxy_username' );
1839
- delete_option( 'mo2f_proxy_password' );
1840
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "Proxy Configurations Reset." ) );
1841
- $this->mo_auth_show_success_message();
 
 
 
 
 
 
 
 
1842
  }
1843
 
1844
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_enable_2FA_option' ) {
1845
- update_option( 'mo2f_enable_2fa', isset( $_POST['mo2f_enable_2fa'] ) ? $_POST['mo2f_enable_2fa'] : 0 );
 
 
 
 
 
 
 
 
 
1846
  }
1847
 
1848
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_enable_2FA_on_login_page_option' ) {
1849
- update_option( 'mo2f_enable_2fa_prompt_on_login_page', isset( $_POST['mo2f_enable_2fa_prompt_on_login_page'] ) ? $_POST['mo2f_enable_2fa_prompt_on_login_page'] : 0 );
 
 
 
 
 
 
 
 
 
1850
  }
1851
 
1852
 
1853
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo_2factor_test_authentication_method' ) {
 
 
 
 
 
 
1854
 
1855
- update_user_meta( $user->ID, 'test_2FA', 1 );
 
 
1856
 
1857
 
1858
- $selected_2FA_method = $_POST['mo2f_configured_2FA_method_test'];
1859
- $selected_2FA_method_server = MO2f_Utility::mo2f_decode_2_factor( $selected_2FA_method, "server" );
1860
- $customer = new Customer_Setup();
1861
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1862
- $customer_key = get_option( 'mo2f_customerKey' );
1863
- $api_key = get_option( 'mo2f_api_key' );
1864
 
1865
- if ( $selected_2FA_method == 'Security Questions' ) {
1866
- $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
1867
 
1868
- if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate KBA Questions*/
1869
- if ( $response['status'] == 'SUCCESS' ) {
1870
- $_SESSION['mo2f_transactionId'] = $response['txId'];
1871
- update_option( 'mo2f_transactionId', $response['txId'] );
1872
- $questions = array();
1873
- $questions[0] = $response['questions'][0]['question'];
1874
- $questions[1] = $response['questions'][1]['question'];
1875
- $_SESSION['mo_2_factor_kba_questions'] = $questions;
1876
- update_option( 'kba_questions', $questions );
1877
 
1878
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ANSWER_SECURITY_QUESTIONS" ) );
1879
- $this->mo_auth_show_success_message();
1880
 
1881
- } else if ( $response['status'] == 'ERROR' ) {
 
 
 
 
 
1882
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_FETCHING_QUESTIONS" ) );
1883
  $this->mo_auth_show_error_message();
1884
 
1885
  }
1886
- } else {
1887
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_FETCHING_QUESTIONS" ) );
1888
- $this->mo_auth_show_error_message();
1889
-
1890
- }
1891
 
1892
- } else if ( $selected_2FA_method == 'miniOrange Push Notification' ) {
1893
- $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
1894
- if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate Qr code */
1895
- if ( $response['status'] == 'ERROR' ) {
1896
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1897
- $this->mo_auth_show_error_message();
1898
-
1899
- } else {
1900
- if ( $response['status'] == 'SUCCESS' ) {
1901
- $_SESSION['mo2f_transactionId'] = $response['txId'];
1902
- update_option( 'mo2f_transactionId', $response['txId'] );
1903
- $_SESSION['mo2f_show_qr_code'] = 'MO_2_FACTOR_SHOW_QR_CODE';
1904
- update_option( 'mo2f_transactionId', $response['txId'] );
1905
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "PUSH_NOTIFICATION_SENT" ) );
1906
- $this->mo_auth_show_success_message();
1907
 
1908
  } else {
1909
- $session_variables = array( 'mo2f_qrCode', 'mo2f_transactionId', 'mo2f_show_qr_code' );
1910
- MO2f_Utility::unset_session_variables( $session_variables );
 
 
 
 
 
1911
 
1912
- delete_option( 'mo2f_transactionId' );
1913
- update_option( 'mo2f_message', 'An error occurred while processing your request. Please Try again.' );
1914
- $this->mo_auth_show_error_message();
1915
 
1916
- }
1917
- }
1918
- } else {
1919
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1920
- $this->mo_auth_show_error_message();
1921
 
1922
- }
1923
- } else if ( $selected_2FA_method == 'OTP Over SMS' ) {
1924
- $phone = $Mo2fdbQueries->get_user_detail( 'mo2f_user_phone', $user->ID );
1925
- $response = json_decode( $customer->send_otp_token( $phone, $selected_2FA_method_server, $customer_key, $api_key ), true );
1926
- if ( strcasecmp( $response['status'], 'SUCCESS' ) == 0 ) {
1927
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "OTP_SENT" ) . ' <b>' . ( $phone ) . '</b>. ' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
1928
- update_option( 'mo2f_number_of_transactions', get_option( 'mo2f_number_of_transactions' ) - 1 );
1929
 
1930
- $_SESSION['mo2f_transactionId'] = $response['txId'];
1931
- update_option( 'mo2f_transactionId', $response['txId'] );
1932
- $this->mo_auth_show_success_message();
 
 
 
 
1933
 
1934
- } else {
1935
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_OTP" ) );
1936
- $this->mo_auth_show_error_message();
1937
 
1938
- }
1939
- } else if ( $selected_2FA_method == 'miniOrange QR Code Authentication' ) {
1940
- $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
1941
 
1942
- if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate Qr code */
 
 
1943
 
1944
- if ( $response['status'] == 'ERROR' ) {
1945
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1946
- $this->mo_auth_show_error_message();
1947
 
1948
- } else {
1949
- if ( $response['status'] == 'SUCCESS' ) {
1950
- $_SESSION['mo2f_qrCode'] = $response['qrCode'];
1951
- $_SESSION['mo2f_transactionId'] = $response['txId'];
1952
- $_SESSION['mo2f_show_qr_code'] = 'MO_2_FACTOR_SHOW_QR_CODE';
1953
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "SCAN_QR_CODE" ) );
1954
- $this->mo_auth_show_success_message();
1955
 
1956
  } else {
1957
- unset( $_SESSION['mo2f_qrCode'] );
1958
- unset( $_SESSION['mo2f_transactionId'] );
1959
- unset( $_SESSION['mo2f_show_qr_code'] );
1960
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1961
- $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
1962
 
 
1963
  }
1964
- }
1965
- } else {
1966
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1967
- $this->mo_auth_show_error_message();
1968
 
 
 
 
1969
  }
1970
- } else if ( $selected_2FA_method == 'Email Verification' ) {
1971
- $this->miniorange_email_verification_call( $user );
1972
- }
1973
 
1974
 
1975
- update_user_meta( $user->ID, 'mo2f_2FA_method_to_test', $selected_2FA_method );
 
1976
 
1977
  }
1978
 
1979
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_go_back' ) {
1980
- $session_variables = array(
1981
- 'mo2f_qrCode',
1982
- 'mo2f_transactionId',
1983
- 'mo2f_show_qr_code',
1984
- 'user_phone',
1985
- 'mo2f_google_auth',
1986
- 'mo2f_mobile_support',
1987
- 'mo2f_authy_keys'
1988
- );
1989
- MO2f_Utility::unset_session_variables( $session_variables );
1990
- delete_option( 'mo2f_transactionId' );
1991
- delete_option( 'user_phone_temp' );
1992
 
1993
- delete_user_meta( $user->ID, 'test_2FA' );
1994
- delete_user_meta( $user->ID, 'configure_2FA' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1995
  }
1996
 
1997
  }
@@ -2176,7 +2570,11 @@ class Miniorange_Authentication {
2176
  global $Mo2fdbQueries;
2177
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
2178
  $google_auth = new Miniorange_Rba_Attributes();
2179
- $google_response = json_decode( $google_auth->mo2f_google_auth_service( $email ), true );
 
 
 
 
2180
  if ( json_last_error() == JSON_ERROR_NONE ) {
2181
  if ( $google_response['status'] == 'SUCCESS' ) {
2182
  $mo2f_google_auth = array();
@@ -2366,6 +2764,10 @@ class Miniorange_Authentication {
2366
  }
2367
 
2368
  function mo_auth_activate() {
 
 
 
 
2369
  if ( get_option( 'mo2f_customerKey' ) && ! get_option( 'mo2f_is_NC' ) ) {
2370
  update_option( 'mo2f_is_NC', 0 );
2371
  } else {
3
  * Plugin Name: miniOrange 2 Factor Authentication
4
  * Plugin URI: https://miniorange.com
5
  * Description: This plugin provides various two-factor authentication methods as an additional layer of security after the default wordpress login. We Support Google Authenticator, QR Code, Push Notification, Soft Token and Security Questions(KBA) for 1 User in the free version of the plugin.
6
+ * Version: 5.1.9
7
  * Author: miniOrange
8
  * Author URI: https://miniorange.com
9
  * License: GPL2
171
  }
172
 
173
  function mo2f_update_db_check() {
174
+
175
+ if(get_option('mo2f_encryption_key',"not_exits")=="not_exits"){
176
+ $get_encryption_key = MO2f_Utility::random_str(40);
177
+ update_option('mo2f_encryption_key',$get_encryption_key);
178
+
179
+ }
180
  global $Mo2fdbQueries;
181
  $user_id = get_option( 'mo2f_miniorange_admin' );
182
  $current_db_version = get_option( 'mo2f_dbversion' );
439
  }
440
 
441
  function mo_2_factor_enable_frontend_style() {
442
+ wp_enqueue_style( 'mo2f_frontend_login_style', plugins_url( 'includes/css/front_end_login.css?version=5.1.9', __FILE__ ) );
443
+ wp_enqueue_style( 'bootstrap_style', plugins_url( 'includes/css/bootstrap.min.css?version=5.1.9', __FILE__ ) );
444
+ wp_enqueue_style( 'mo_2_factor_admin_settings_phone_style', plugins_url( 'includes/css/phone.css?version=5.1.9', __FILE__ ) );
445
  wp_enqueue_style( 'mo_2_factor_wpb-fa', plugins_url( 'includes/css/font-awesome.min.css', __FILE__ ) );
446
+ wp_enqueue_style( 'mo2f_login_popup_style', plugins_url( 'includes/css/mo2f_login_popup_ui.css?version=5.1.9', __FILE__ ) );
447
  }
448
 
449
  function plugin_settings_style( $mo2fa_hook_page ) {
450
  if ( 'toplevel_page_miniOrange_2_factor_settings' != $mo2fa_hook_page ) {
451
  return;
452
  }
453
+ wp_enqueue_style( 'mo_2_factor_admin_settings_style', plugins_url( 'includes/css/style_settings.css?version=5.1.9', __FILE__ ) );
454
+ wp_enqueue_style( 'mo_2_factor_admin_settings_phone_style', plugins_url( 'includes/css/phone.css?version=5.1.9', __FILE__ ) );
455
+ wp_enqueue_style( 'bootstrap_style', plugins_url( 'includes/css/bootstrap.min.css?version=5.1.9', __FILE__ ) );
456
+ wp_enqueue_style( 'bootstrap_style_ass', plugins_url( 'includes/css/bootstrap-tour-standalone.css?version=5.1.9', __FILE__ ) );
457
  wp_enqueue_style( 'mo_2_factor_wpb-fa', plugins_url( 'includes/css/font-awesome.min.css', __FILE__ ) );
458
  }
459
 
464
  wp_enqueue_script( 'jquery' );
465
  wp_enqueue_script( 'mo_2_factor_admin_settings_phone_script', plugins_url( 'includes/js/phone.js', __FILE__ ) );
466
  wp_enqueue_script( 'bootstrap_script', plugins_url( 'includes/js/bootstrap.min.js', __FILE__ ) );
467
+ wp_enqueue_script( 'bootstrap_script_hehe', plugins_url( 'includes/js/bootstrap-tour-standalone.min.js', __FILE__ ) );
468
+
469
  }
470
 
471
  function miniorange_auth_save_settings() {
487
  if ( current_user_can( 'manage_options' ) ) {
488
 
489
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_deactivate_account" ) {
490
+ $nonce = $_POST['mo_auth_deactivate_account_nonce'];
491
+ if ( ! wp_verify_nonce( $nonce, 'mo-auth-deactivate-account-nonce' ) ) {
492
+ $error = new WP_Error();
493
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
494
+
495
+ return $error;
496
+ } else {
497
+ $url = admin_url( 'plugins.php' );
498
+ wp_redirect( $url );
499
+ }
500
  }
501
 
502
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_remove_account" ) {
503
+ $nonce = $_POST['mo_auth_remove_account_nonce'];
504
+ if ( ! wp_verify_nonce( $nonce, 'mo-auth-remove-account-nonce' ) ) {
505
+ $error = new WP_Error();
506
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
507
+ return $error;
508
+ } else {
509
+ update_option( 'mo2f_register_with_another_email', 1 );
510
+ $this->mo_auth_deactivate();
511
+ }
512
  }
513
 
514
 
515
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo2f_save_proxy_settings" ) {
516
+ $nonce = $_POST['mo2f_save_proxy_settings_nonce'];
517
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-save-proxy-settings-nonce' ) ) {
518
+ $error = new WP_Error();
519
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
520
+ return $error;
521
+ } else {
522
+ $proxyHost = $_POST['proxyHost'];
523
+ $portNumber = $_POST['portNumber'];
524
+ $proxyUsername = $_POST['proxyUsername'];
525
+ $proxyPassword = $_POST['proxyPass'];
526
+
527
+ update_option( 'mo2f_proxy_host', $proxyHost );
528
+ update_option( 'mo2f_port_number', $portNumber );
529
+ update_option( 'mo2f_proxy_username', $proxyUsername );
530
+ update_option( 'mo2f_proxy_password', $proxyPassword );
531
+ update_option( 'mo2f_message', 'Proxy settings saved successfully.' );
532
+ $this->mo_auth_show_success_message();
533
+ }
534
 
535
  }
536
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_register_customer" ) { //register the admin to miniOrange
537
+ //miniorange_register_customer_nonce
538
+ $nonce = $_POST['miniorange_register_customer_nonce'];
539
+ if ( ! wp_verify_nonce( $nonce, 'miniorange-register-customer-nonce' ) ) {
540
+ $error = new WP_Error();
541
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
542
 
543
+ return $error;
544
+ } else {
545
  //validate and sanitize
546
  $email = '';
547
  $password = '';
594
  }
595
  }
596
  }
597
+ }
598
 
599
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo2f_goto_verifycustomer" ) {
600
+ $nonce = $_POST['mo2f_goto_verifycustomer_nonce'];
601
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-goto-verifycustomer-nonce' ) ) {
602
+ $error = new WP_Error();
603
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
604
+ return $error;
605
+ } else {
606
+ $Mo2fdbQueries->insert_user( $user_id, array( 'user_id' => $user_id ) );
607
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ENTER_YOUR_EMAIL_PASSWORD" ) );
608
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_VERIFY_CUSTOMER' ) );
609
+ }
610
  }
611
 
612
 
613
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo_2factor_gobackto_registration_page' ) { //back to registration page for admin
614
+ $nonce = $_POST['mo_2factor_gobackto_registration_page_nonce'];
615
+ if ( ! wp_verify_nonce( $nonce, 'mo-2factor-gobackto-registration-page-nonce' ) ) {
616
+ $error = new WP_Error();
617
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
618
+ return $error;
619
+ } else {
620
+ delete_option( 'mo2f_email' );
621
+ delete_option( 'mo2f_password' );
622
+ update_option( 'mo2f_message', "" );
623
 
624
+ MO2f_Utility::unset_session_variables( 'mo2f_transactionId' );
625
+ delete_option( 'mo2f_transactionId' );
626
+ delete_user_meta( $user->ID, 'mo2f_sms_otp_count' );
627
+ delete_user_meta( $user->ID, 'mo2f_email_otp_count' );
628
+ delete_user_meta( $user->ID, 'mo2f_email_otp_count' );
629
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'REGISTRATION_STARTED' ) );
630
+ }
631
 
632
  }
633
 
634
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_registration_closed' ) {
635
+ $nonce = $_POST['mo2f_registration_closed_nonce'];
636
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-registration-closed-nonce' ) ) {
637
+ $error = new WP_Error();
638
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
639
+ return $error;
640
+ } else {
641
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => '' ) );
642
+ delete_user_meta( $user->ID, 'register_account' );
643
+ }
644
  }
645
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_verify_customer" ) { //register the admin to miniOrange if already exist
646
 
647
+ $nonce = $_POST['miniorange_verify_customer_nonce'];
648
+
649
+ if ( ! wp_verify_nonce( $nonce, 'miniorange-verify-customer-nonce' ) ) {
650
+ $error = new WP_Error();
651
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
652
 
653
+ return $error;
 
 
 
 
654
  } else {
655
+
656
+ //validation and sanitization
657
+ $email = '';
658
+ $password = '';
659
+ $Mo2fdbQueries->insert_user( $user_id, array( 'user_id' => $user_id ) );
660
 
661
+
662
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['email'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['password'] ) ) {
663
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
 
 
 
 
 
664
  $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
 
 
665
 
666
+ return;
667
+ } else {
668
+ $email = sanitize_email( $_POST['email'] );
669
+ $password = sanitize_text_field( $_POST['password'] );
670
+ }
671
 
672
+ update_option( 'mo2f_email', $email );
673
+ update_option( 'mo2f_password', stripslashes( $password ) );
674
+ $customer = new Customer_Setup();
675
+ $content = $customer->get_customer_key();
676
+ $customerKey = json_decode( $content, true );
677
+
678
+ if ( json_last_error() == JSON_ERROR_NONE ) {
679
+ if ( is_array( $customerKey ) && array_key_exists( "status", $customerKey ) && $customerKey['status'] == 'ERROR' ) {
680
+ update_option( 'mo2f_message', Mo2fConstants::langTranslate( $customerKey['message'] ) );
681
+ $this->mo_auth_show_error_message();
682
+ } else if ( is_array( $customerKey ) ) {
683
+ if ( isset( $customerKey['id'] ) && ! empty( $customerKey['id'] ) ) {
684
+ update_option( 'mo2f_customerKey', $customerKey['id'] );
685
+ update_option( 'mo2f_api_key', $customerKey['apiKey'] );
686
+ update_option( 'mo2f_customer_token', $customerKey['token'] );
687
+ update_option( 'mo2f_app_secret', $customerKey['appSecret'] );
688
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo2f_user_phone' => $customerKey['phone'] ) );
689
+ update_option( 'mo2f_miniorange_admin', $user->ID );
690
 
691
+ $mo2f_emailVerification_config_status = get_option( 'mo2f_is_NC' ) == 0 ? true : false;
 
 
 
692
 
693
+ delete_option( 'mo2f_password' );
694
+ update_option( 'mo_2factor_admin_registration_status', 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' );
 
 
695
 
696
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
697
+ 'mo2f_EmailVerification_config_status' => $mo2f_emailVerification_config_status,
698
+ 'mo2f_user_email' => get_option( 'mo2f_email' ),
699
+ 'user_registration_with_miniorange' => 'SUCCESS',
700
+ 'mo2f_2factor_enable_2fa_byusers' => 1,
701
+ ) );
702
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_PLUGIN_SETTINGS';
703
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
704
+ $configured_2FA_method = 'NONE';
705
+ $user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
706
+ $enduser = new Two_Factor_Setup();
707
+ $userinfo = json_decode( $enduser->mo2f_get_userinfo( $user_email ), true );
708
 
709
+ $mo2f_second_factor = 'NONE';
710
+ if ( json_last_error() == JSON_ERROR_NONE ) {
711
+ if ( $userinfo['status'] == 'SUCCESS' ) {
712
+ $mo2f_second_factor = mo2f_update_and_sync_user_two_factor( $user->ID, $userinfo );
 
713
 
 
 
 
 
 
 
 
714
  }
715
  }
716
+ if ( $mo2f_second_factor != 'NONE' ) {
717
+ $configured_2FA_method = MO2f_Utility::mo2f_decode_2_factor( $mo2f_second_factor, "servertowpdb" );
718
+
719
+ if ( get_option( 'mo2f_is_NC' ) == 0 ) {
720
+
721
+ $auth_method_abr = str_replace( ' ', '', $configured_2FA_method );
722
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
723
+ 'mo2f_configured_2FA_method' => $configured_2FA_method,
724
+ 'mo2f_' . $auth_method_abr . '_config_status' => true
725
+ ) );
726
+
727
+ } else {
728
+ if ( in_array( $configured_2FA_method, array(
729
+ 'Email Verification',
730
+ 'Authy Authenticator',
731
+ 'OTP over SMS'
732
+ ) ) ) {
733
+ $enduser->mo2f_update_userinfo( $user_email, 'NONE', null, '', true );
734
+ }
735
+ }
736
 
737
 
738
+ }
739
 
740
+ $mo2f_message = Mo2fConstants:: langTranslate( "ACCOUNT_RETRIEVED_SUCCESSFULLY" );
741
+ if ( $configured_2FA_method != 'NONE' && get_option( 'mo2f_is_NC' ) == 0 ) {
742
+ $mo2f_message .= ' <b>' . $configured_2FA_method . '</b> ' . Mo2fConstants:: langTranslate( "DEFAULT_2ND_FACTOR" ) . '.';
743
+ }
744
+ $mo2f_message .= ' ' . '<a href=\"admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mobile_configure\" >' . Mo2fConstants:: langTranslate( "CLICK_HERE" ) . '</a> ' . Mo2fConstants:: langTranslate( "CONFIGURE_2FA" );
745
 
746
+ delete_user_meta( $user->ID, 'register_account' );
747
 
748
+ $mo2f_customer_selected_plan = get_option( 'mo2f_customer_selected_plan' );
749
+ if ( ! empty( $mo2f_customer_selected_plan ) ) {
750
+ delete_option( 'mo2f_customer_selected_plan' );
751
+ header( 'Location: admin.php?page=miniOrange_2_factor_settings&mo2f_tab=mo2f_pricing' );
752
+ } else if ( $mo2f_second_factor == 'NONE' ) {
753
+ update_user_meta( $user->ID, 'configure_2FA', 1 );
754
+ }
755
 
756
 
757
+ update_option( 'mo2f_message', $mo2f_message );
758
+ } else {
759
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_EMAIL_OR_PASSWORD" ) );
760
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_VERIFY_CUSTOMER';
761
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
762
+
763
+ }
764
 
765
  }
766
+ } else {
767
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_EMAIL_OR_PASSWORD" ) );
768
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_VERIFY_CUSTOMER';
769
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
770
 
771
  }
 
 
 
 
772
 
773
+ delete_option( 'mo2f_password' );
774
  }
 
 
775
  }
776
 
777
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo_2factor_phone_verification' ) { //at registration time
808
  }
809
 
810
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_resend_otp" ) { //resend OTP over email for admin
811
+
812
+ $nonce = $_POST['mo_2factor_resend_otp_nonce'];
813
+
814
+ if ( ! wp_verify_nonce( $nonce, 'mo-2factor-resend-otp-nonce' ) ) {
815
+ $error = new WP_Error();
816
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
817
+
818
+ return $error;
819
+ } else {
820
+ $customer = new Customer_Setup();
821
+ $content = json_decode( $customer->send_otp_token( get_option( 'mo2f_email' ), 'EMAIL', $defaultCustomerKey, $defaultApiKey ), true );
822
+ if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) {
823
+ if ( get_user_meta( $user->ID, 'mo2f_email_otp_count', true ) ) {
824
+ update_user_meta( $user->ID, 'mo2f_email_otp_count', get_user_meta( $user->ID, 'mo2f_email_otp_count', true ) + 1 );
825
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "RESENT_OTP" ) . ' <b>( ' . get_user_meta( $user->ID, 'mo2f_email_otp_count', true ) . ' )</b> to <b>' . ( get_option( 'mo2f_email' ) ) . '</b> ' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
826
+ } else {
827
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "OTP_SENT" ) . '<b> ' . ( get_option( 'mo2f_email' ) ) . ' </b>' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
828
+ update_user_meta( $user->ID, 'mo2f_email_otp_count', 1 );
829
+ }
830
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_OTP_DELIVERED_SUCCESS';
831
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
832
+ update_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account', $content['txId'] );
833
+ $this->mo_auth_show_success_message();
834
  } else {
835
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_EMAIL" ) );
836
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_OTP_DELIVERED_FAILURE';
837
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
838
+ $this->mo_auth_show_error_message();
839
  }
 
 
 
 
 
 
 
 
 
840
  }
841
 
842
 
850
 
851
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_validate_otp" ) { //validate OTP over email for admin
852
 
853
+ $nonce = $_POST['mo_2factor_validate_otp_nonce'];
854
+
855
+ if ( ! wp_verify_nonce( $nonce, 'mo-2factor-validate-otp-nonce' ) ) {
856
+ $error = new WP_Error();
857
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
858
 
859
+ return $error;
860
  } else {
861
+ //validation and sanitization
862
+ $otp_token = '';
863
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
864
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
865
+ $this->mo_auth_show_error_message();
866
 
867
+ return;
868
+ } else {
869
+ $otp_token = sanitize_text_field( $_POST['otp_token'] );
870
+ }
871
 
872
+ $customer = new Customer_Setup();
873
 
874
+ $transactionId = get_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account', true );
875
 
876
+ $content = json_decode( $customer->validate_otp_token( 'EMAIL', null, $transactionId, $otp_token, $defaultCustomerKey, $defaultApiKey ), true );
 
877
 
878
+ if ( $content['status'] == 'ERROR' ) {
879
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $content['message'] ) );
880
 
881
+ } else {
 
 
 
 
 
 
 
882
 
883
+ if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated
884
+ $this->mo2f_create_customer( $user );
885
+ delete_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account' );
886
+ delete_user_meta( $user->ID, 'register_account' );
887
+ update_user_meta( $user->ID, 'configure_2FA', 1 );
888
+ } else { // OTP Validation failed.
889
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
890
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_OTP_DELIVERED_FAILURE' ) );
891
+
892
+ }
893
  }
894
  }
895
  }
897
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_validate_user_otp" ) { //validate OTP over email for additional admin
898
 
899
  //validation and sanitization
900
+ $nonce = $_POST['mo_2factor_validate_user_otp_nonce'];
901
+
902
+ if ( ! wp_verify_nonce( $nonce, 'mo-2factor-validate-user-otp-nonce' ) ) {
903
+ $error = new WP_Error();
904
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
905
 
906
+ return $error;
907
  } else {
908
+ $otp_token = '';
909
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
910
+ update_option( 'mo2f_message', 'All the fields are required. Please enter valid entries.' );
911
+ $this->mo_auth_show_error_message();
912
 
913
+ return;
914
+ } else {
915
+ $otp_token = sanitize_text_field( $_POST['otp_token'] );
916
+ }
917
 
918
+ $user_email = get_user_meta( $user->ID, 'user_email', true );
 
 
919
 
920
+ //if(!MO2f_Utility::check_if_email_is_already_registered($user_email)){
921
+ $customer = new Customer_Setup();
922
+ $mo2f_transactionId = isset( $_SESSION['mo2f_transactionId'] ) && ! empty( $_SESSION['mo2f_transactionId'] ) ? $_SESSION['mo2f_transactionId'] : get_option( 'mo2f_transactionId' );
923
 
924
+ $content = json_decode( $customer->validate_otp_token( 'EMAIL', '', $mo2f_transactionId, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
925
+
926
+ if ( $content['status'] == 'ERROR' ) {
927
+ update_option( 'mo2f_message', $content['message'] );
 
 
 
 
 
 
928
  $this->mo_auth_show_error_message();
929
+ } else {
930
+ if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated and generate QRCode
931
+ $this->mo2f_create_user( $user, $user_email );
932
+ delete_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account' );
933
+ } else {
934
+ update_option( 'mo2f_message', 'Invalid OTP. Please try again.' );
935
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_OTP_DELIVERED_FAILURE' ) );
936
+ $this->mo_auth_show_error_message();
937
+ }
938
  }
939
+ /*}else{
940
+ update_option('mo2f_message','The email is already used by other user. Please register with other email by clicking on Back button.');
941
+ $this->mo_auth_show_error_message();
942
+ }*/
943
  }
 
 
 
 
944
  }
945
 
946
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_send_query" ) { //Help me or support
947
+ $nonce = $_POST['mo_2factor_send_query_nonce'];
948
+
949
+ if ( ! wp_verify_nonce( $nonce, 'mo-2factor-send-query-nonce' ) ) {
950
+ $error = new WP_Error();
951
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
952
 
953
+ return $error;
954
  } else {
955
+
956
+ $query = '';
957
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['EMAIL_MANDATORY'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['query'] ) ) {
958
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "EMAIL_MANDATORY" ) );
959
+ $this->mo_auth_show_error_message();
960
+
961
+ return;
962
+ } else {
963
+ $query = sanitize_text_field( $_POST['query'] );
964
+ $email = sanitize_text_field( $_POST['EMAIL_MANDATORY'] );
965
+ $phone = sanitize_text_field( $_POST['query_phone'] );
966
+ $contact_us = new Customer_Setup();
967
+ $submited = json_decode( $contact_us->submit_contact_us( $email, $phone, $query ), true );
968
+ if ( json_last_error() == JSON_ERROR_NONE ) {
969
+ if ( is_array( $submited ) && array_key_exists( 'status', $submited ) && $submited['status'] == 'ERROR' ) {
970
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $submited['message'] ) );
971
  $this->mo_auth_show_error_message();
972
  } else {
973
+ if ( $submited == false ) {
974
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SUBMITTING_QUERY" ) );
975
+ $this->mo_auth_show_error_message();
976
+ } else {
977
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "QUERY_SUBMITTED_SUCCESSFULLY" ) );
978
+ $this->mo_auth_show_success_message();
979
+ }
980
  }
981
  }
 
982
 
983
+ }
984
  }
985
  }
986
 
993
  }
994
 
995
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo_auth_login_settings_save' ) {
996
+ $nonce = $_POST['mo_auth_login_settings_save_nonce'];
997
+
998
+ if ( ! wp_verify_nonce( $nonce, 'mo-auth-login-settings-save-nonce' ) ) {
999
+ $error = new WP_Error();
1000
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1001
+
1002
+ return $error;
1003
+ } else {
1004
+ $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID );
1005
+ if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
1006
 
1007
+ update_option( 'mo2f_login_option', isset( $_POST['mo2f_login_option'] ) ? $_POST['mo2f_login_option'] : 0 );
1008
+ update_option( 'mo2f_remember_device', isset( $_POST['mo2f_remember_device'] ) ? $_POST['mo2f_remember_device'] : 0 );
1009
+ if ( get_option( 'mo2f_login_option' ) == 0 ) {
1010
 
1011
+ update_option( 'mo2f_remember_device', 0 );
1012
+ }
1013
+ update_option( 'mo2f_enable_forgotphone', isset( $_POST['mo2f_forgotphone'] ) ? $_POST['mo2f_forgotphone'] : 0 );
1014
+ update_option( 'mo2f_enable_login_with_2nd_factor', isset( $_POST['mo2f_login_with_username_and_2factor'] ) ? $_POST['mo2f_login_with_username_and_2factor'] : 0 );
1015
+ update_option( 'mo2f_enable_xmlrpc', isset( $_POST['mo2f_enable_xmlrpc'] ) ? $_POST['mo2f_enable_xmlrpc'] : 0 );
1016
 
1017
 
1018
+ if ( get_option( 'mo2f_remember_device' ) && ! get_option( 'mo2f_app_secret' ) ) {
1019
+ $get_app_secret = new Miniorange_Rba_Attributes();
1020
+ $rba_response = json_decode( $get_app_secret->mo2f_get_app_secret(), true ); //fetch app secret
1021
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1022
+ if ( $rba_response['status'] == 'SUCCESS' ) {
1023
+ update_option( 'mo2f_app_secret', $rba_response['appSecret'] );
1024
+ } else {
1025
+ update_option( 'mo2f_remember_device', 0 );
1026
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_SETTINGS" ) );
1027
+ $this->mo_auth_show_error_message();
1028
+ }
1029
  } else {
1030
  update_option( 'mo2f_remember_device', 0 );
1031
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_SETTINGS" ) );
1032
  $this->mo_auth_show_error_message();
1033
  }
 
 
 
 
1034
  }
 
1035
 
1036
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "SETTINGS_SAVED" ) );
1037
+ $this->mo_auth_show_success_message();
1038
 
1039
+ } else {
1040
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQUEST" ) );
1041
+ $this->mo_auth_show_error_message();
1042
+ }
1043
  }
1044
  }
1045
 
1046
 
1047
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_sync_sms_transactions" ) {
1048
+
1049
  $customer = new Customer_Setup();
1050
  $content = json_decode( $customer->get_customer_transactions( get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1051
  if ( ! array_key_exists( 'smsRemaining', $content ) ) {
1064
 
1065
  }
1066
 
1067
+ if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_fix_database_error' ) {
1068
+ $nonce = $_POST['mo2f_fix_database_error_nonce'];
1069
+
1070
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-fix-database-error-nonce' ) ) {
1071
+ $error = new WP_Error();
1072
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1073
+
1074
+ return $error;
1075
+ } else {
1076
+ global $Mo2fdbQueries;
1077
+
1078
+ $Mo2fdbQueries->database_table_issue();
1079
+
1080
+ }
1081
+ }
1082
+
1083
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_skip_feedback' ) {
1084
 
1085
  //update_option( 'mo2f_feedback_form', 1 );
1086
+ $nonce = $_POST['mo2f_skip_feedback_nonce'];
1087
+
1088
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-skip-feedback-nonce' ) ) {
1089
+ $error = new WP_Error();
1090
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1091
+
1092
+ return $error;
1093
+ } else {
1094
+ deactivate_plugins( '/miniorange-2-factor-authentication/miniorange_2_factor_settings.php' );
1095
+ }
1096
 
1097
  }
1098
  if ( isset( $_POST['mo2f_feedback'] ) and $_POST['mo2f_feedback'] == 'mo2f_feedback' ) {
1099
+
1100
+ $nonce = $_POST['mo2f_feedback_nonce'];
1101
+
1102
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-feedback-nonce' ) ) {
1103
+ $error = new WP_Error();
1104
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1105
+
1106
+ return $error;
1107
+ } else {
1108
+ $reasons_not_to_worry_about = array( "Upgrading to Premium", "Temporary deactivation - Testing" );
1109
 
1110
+ $message = 'Plugin Deactivated:';
 
 
1111
 
1112
+ if ( isset( $_POST['deactivate_plugin'] ) ) {
1113
+ if ( $_POST['query_feedback'] == '' and $_POST['deactivate_plugin'] == 'Other Reasons:' ) {
1114
+ // feedback add
1115
+ update_option( 'mo2f_message', 'Please let us know the reason for deactivation so that we improve the user experience.' );
1116
+ } else {
1117
 
1118
+ if ( ! in_array( $_POST['deactivate_plugin'], $reasons_not_to_worry_about ) ) {
1119
 
1120
+ $message .= $_POST['deactivate_plugin'];
1121
 
1122
+ if ( $_POST['query_feedback'] != '' ) {
1123
+ $message .= ':' . $_POST['query_feedback'];
1124
+ }
1125
 
1126
 
1127
+ if($_POST['deactivate_plugin'] == "Conflicts with other plugins"){
1128
+ $plugin_selected = $_POST['plugin_selected'];
1129
+ $plugin = MO2f_Utility::get_plugin_name_by_identifier($plugin_selected);
1130
 
1131
+ $message .= ", Plugin selected - " . $plugin . ".";
1132
+ }
1133
 
1134
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1135
+ if ( $email == '' ) {
1136
+ $email = $user->user_email;
1137
+ }
1138
 
1139
+ $phone = $Mo2fdbQueries->get_user_detail( 'mo2f_user_phone', $user->ID );;
1140
 
1141
+ $contact_us = new Customer_Setup();
1142
+ $submited = json_decode( $contact_us->send_email_alert( $email, $phone, $message ), true );
1143
 
1144
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1145
+ if ( is_array( $submited ) && array_key_exists( 'status', $submited ) && $submited['status'] == 'ERROR' ) {
1146
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $submited['message'] ) );
 
 
 
 
1147
  $this->mo_auth_show_error_message();
1148
  } else {
1149
+ if ( $submited == false ) {
1150
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SUBMITTING_QUERY" ) );
1151
+ $this->mo_auth_show_error_message();
1152
+ } else {
1153
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "QUERY_SUBMITTED_SUCCESSFULLY" ) );
1154
+ $this->mo_auth_show_success_message();
1155
+ //update_option( 'mo2f_feedback_form', 1 );
1156
+ }
1157
  }
1158
  }
1159
  }
 
1160
 
1161
+ //update_option( 'mo2f_feedback_form', 1 );
1162
+ deactivate_plugins( '/miniorange-2-factor-authentication/miniorange_2_factor_settings.php' );
1163
 
1164
+ }
1165
 
1166
+ } else {
1167
+ update_option( 'mo2f_message', 'Please Select one of the reasons if your reason isnot mention please select Other Reasons' );
1168
 
1169
+ }
1170
  }
1171
 
1172
  }
1173
 
1174
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_2factor_resend_user_otp" ) { //resend OTP over email for additional admin and non-admin user
1175
+
1176
+ $nonce = $_POST['mo_2factor_resend_user_otp_nonce'];
1177
+
1178
+ if ( ! wp_verify_nonce( $nonce, 'mo-2factor-resend-user-otp-nonce' ) ) {
1179
+ $error = new WP_Error();
1180
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1181
+
1182
+ return $error;
1183
+ } else {
1184
+ $customer = new Customer_Setup();
1185
+ $content = json_decode( $customer->send_otp_token( get_user_meta( $user->ID, 'user_email', true ), 'EMAIL', get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1186
+ if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) {
1187
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "OTP_SENT" ) . ' <b>' . ( get_user_meta( $user->ID, 'user_email', true ) ) . '</b>. ' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
1188
+ update_user_meta( $user->ID, 'mo_2fa_verify_otp_create_account', $content['txId'] );
1189
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_OTP_DELIVERED_SUCCESS';
1190
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
1191
+ $this->mo_auth_show_success_message();
1192
+ } else {
1193
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_EMAIL" ) );
1194
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_OTP_DELIVERED_FAILURE';
1195
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => $mo_2factor_user_registration_status ) );
1196
+ $this->mo_auth_show_error_message();
1197
 
1198
+ }
1199
+ }
1200
 
1201
  }
1202
 
1203
  if ( isset( $_POST['option'] ) and ( $_POST['option'] == "mo2f_configure_miniorange_authenticator_validate" || $_POST['option'] == 'mo_auth_mobile_reconfiguration_complete' ) ) { //mobile registration successfully complete for all users
1204
 
1205
+ $nonce = $_POST['mo2f_configure_miniorange_authenticator_validate_nonce'];
1206
+
1207
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-configure-miniorange-authenticator-validate-nonce' ) ) {
1208
+ $error = new WP_Error();
1209
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1210
 
1211
+ return $error;
1212
+ } else {
1213
+ delete_option( 'mo2f_transactionId' );
1214
+ $session_variables = array( 'mo2f_qrCode', 'mo2f_transactionId', 'mo2f_show_qr_code' );
1215
+ MO2f_Utility::unset_session_variables( $session_variables );
1216
 
1217
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1218
+ $TwoFA_method_to_configure = get_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', true );
1219
+ $enduser = new Two_Factor_Setup();
1220
+ $current_method = MO2f_Utility::mo2f_decode_2_factor( $TwoFA_method_to_configure, "server" );
1221
 
1222
+ $response = json_decode( $enduser->mo2f_update_userinfo( $email, $current_method, null, null, null ), true );
 
 
1223
 
1224
+ if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate Qr code */
1225
+ if ( $response['status'] == 'ERROR' ) {
1226
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1227
 
1228
+ $this->mo_auth_show_error_message();
1229
 
 
1230
 
1231
+ } else if ( $response['status'] == 'SUCCESS' ) {
1232
 
1233
+ $selectedMethod = $TwoFA_method_to_configure;
1234
 
1235
+ delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
1236
 
 
 
 
 
 
 
 
 
 
1237
 
1238
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
1239
+ 'mo2f_configured_2FA_method' => $selectedMethod,
1240
+ 'mobile_registration_status' => true,
1241
+ 'mo2f_miniOrangeQRCodeAuthentication_config_status' => true,
1242
+ 'mo2f_miniOrangeSoftToken_config_status' => true,
1243
+ 'mo2f_miniOrangePushNotification_config_status' => true,
1244
+ 'user_registration_with_miniorange' => 'SUCCESS',
1245
+ 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS'
1246
+ ) );
1247
 
1248
+ $is_nc_with_unlimited_users = get_option( 'mo2f_is_NC' ) && ! get_option( 'mo2f_is_NNC' );
 
 
1249
 
 
 
1250
 
1251
+ delete_user_meta( $user->ID, 'configure_2FA' );
1252
+ mo2f_display_test_2fa_notification($user);
 
1253
 
1254
+ } else {
1255
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1256
+ $this->mo_auth_show_error_message();
1257
 
1258
+ }
1259
+
1260
+ } else {
1261
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1262
+ $this->mo_auth_show_error_message();
1263
+ }
1264
+ }
1265
 
1266
  }
1267
 
1268
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_mobile_authenticate_success' ) { // mobile registration for all users(common)
 
 
 
 
 
1269
 
1270
+ $nonce = $_POST['mo2f_mobile_authenticate_success_nonce'];
1271
+
1272
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-mobile-authenticate-success-nonce' ) ) {
1273
+ $error = new WP_Error();
1274
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1275
 
1276
+ return $error;
1277
+ } else {
1278
+
1279
+ if ( current_user_can( 'manage_options' ) ) {
1280
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1281
+ } else {
1282
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1283
+ }
1284
 
1285
+ $session_variables = array( 'mo2f_qrCode', 'mo2f_transactionId', 'mo2f_show_qr_code' );
1286
+ MO2f_Utility::unset_session_variables( $session_variables );
1287
+
1288
+ delete_user_meta( $user->ID, 'test_2FA' );
1289
+ $this->mo_auth_show_success_message();
1290
+ }
1291
  }
1292
 
1293
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_mobile_authenticate_error' ) { //mobile registration failed for all users(common)
1294
+ $nonce = $_POST['mo2f_mobile_authenticate_error_nonce'];
1295
+
1296
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-mobile-authenticate-error-nonce' ) ) {
1297
+ $error = new WP_Error();
1298
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1299
+
1300
+ return $error;
1301
+ } else {
1302
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "AUTHENTICATION_FAILED" ) );
1303
+ MO2f_Utility::unset_session_variables( 'mo2f_show_qr_code' );
1304
+ $this->mo_auth_show_error_message();
1305
+ }
1306
 
1307
  }
1308
 
1309
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_setting_configuration" ) // redirect to setings page
1310
+ {
1311
+
1312
  $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS' ) );
1313
 
1314
  }
1315
 
1316
  if ( isset( $_POST['option'] ) and $_POST['option'] == "mo_auth_refresh_mobile_qrcode" ) { // refrsh Qrcode for all users
1317
+
1318
+ $nonce = $_POST['mo_auth_refresh_mobile_qrcode_nonce'];
1319
+
1320
+ if ( ! wp_verify_nonce( $nonce, 'mo-auth-refresh-mobile-qrcode-nonce' ) ) {
1321
+ $error = new WP_Error();
1322
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1323
 
1324
+ return $error;
 
 
 
 
 
 
 
1325
  } else {
1326
+ $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID );
1327
+ if ( in_array( $mo_2factor_user_registration_status, array(
1328
+ 'MO_2_FACTOR_INITIALIZE_TWO_FACTOR',
1329
+ 'MO_2_FACTOR_INITIALIZE_MOBILE_REGISTRATION',
1330
+ 'MO_2_FACTOR_PLUGIN_SETTINGS'
1331
+ ) ) ) {
1332
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1333
+ $this->mo2f_get_qr_code_for_mobile( $email, $user->ID );
1334
+ } else {
1335
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "REGISTER_WITH_MO" ) );
1336
+ $this->mo_auth_show_error_message();
1337
 
1338
+ }
1339
  }
1340
  }
1341
 
1415
 
1416
 
1417
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo_2factor_backto_user_registration' ) { //back to registration page for additional admin and non-admin
1418
+ $nonce = $_POST['mo_2factor_backto_user_registration_nonce'];
1419
+
1420
+ if ( ! wp_verify_nonce( $nonce, 'mo-2factor-backto-user-registration-nonce' ) ) {
1421
+ $error = new WP_Error();
1422
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1423
 
1424
+ return $error;
1425
+ } else {
1426
+ delete_user_meta( $user->ID, 'user_email' );
1427
+ $Mo2fdbQueries->delete_user_details( $user->ID );
1428
+ MO2f_Utility::unset_session_variables( 'mo2f_transactionId' );
1429
+ delete_option( 'mo2f_transactionId' );
1430
+ }
1431
 
1432
  }
1433
 
1434
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_soft_token' ) { // validate Soft Token during test for all users
1435
+
1436
+ $nonce = $_POST['mo2f_validate_soft_token_nonce'];
1437
+
1438
+
1439
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-validate-soft-token-nonce' ) ) {
1440
+ $error = new WP_Error();
1441
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1442
 
1443
+ return $error;
1444
  } else {
1445
+ $otp_token = '';
1446
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
1447
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ENTER_VALUE" ) );
1448
+ $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
1449
 
1450
+ return;
1451
+ } else {
1452
+ $otp_token = sanitize_text_field( $_POST['otp_token'] );
1453
+ }
1454
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1455
+ $customer = new Customer_Setup();
1456
+ $content = json_decode( $customer->validate_otp_token( 'SOFT TOKEN', $email, null, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1457
+ if ( $content['status'] == 'ERROR' ) {
1458
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $content['message'] ) );
1459
+ $this->mo_auth_show_error_message();
1460
+ } else {
1461
+ if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated and generate QRCode
1462
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1463
 
1464
+ delete_user_meta( $user->ID, 'test_2FA' );
1465
+ $this->mo_auth_show_success_message();
1466
 
 
 
 
1467
 
1468
+ } else { // OTP Validation failed.
1469
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
1470
+ $this->mo_auth_show_error_message();
1471
+
1472
+ }
1473
  }
1474
  }
1475
  }
1476
 
1477
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_otp_over_sms' ) { //validate otp over sms and phone call during test for all users
1478
+
1479
+ $nonce = $_POST['mo2f_validate_otp_over_sms_nonce'];
1480
+
1481
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-validate-otp-over-sms-nonce' ) ) {
1482
+ $error = new WP_Error();
1483
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1484
 
1485
+ return $error;
1486
  } else {
1487
+ $otp_token = '';
1488
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
1489
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ENTER_VALUE" ) );
1490
+ $this->mo_auth_show_error_message();
1491
 
1492
+ return;
1493
+ } else {
1494
+ $otp_token = sanitize_text_field( $_POST['otp_token'] );
1495
+ }
1496
+
1497
+ //if the php session folder has insufficient permissions, temporary options to be used
1498
+ $mo2f_transactionId = isset( $_SESSION['mo2f_transactionId'] ) && ! empty( $_SESSION['mo2f_transactionId'] ) ? $_SESSION['mo2f_transactionId'] : get_option( 'mo2f_transactionId' );
1499
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1500
+ $selected_2_2factor_method = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1501
+ $customer = new Customer_Setup();
1502
+ $content = json_decode( $customer->validate_otp_token( get_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', true ), $email, $mo2f_transactionId, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1503
+
1504
+ if ( $content['status'] == 'ERROR' ) {
1505
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $content['message'] ) );
1506
+ $this->mo_auth_show_error_message();
1507
+ } else {
1508
+ if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated
1509
+ if ( current_user_can( 'manage_options' ) ) {
1510
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1511
+ } else {
1512
+ update_option( 'mo2f_message', Mo2fConstants::langTranslate( "COMPLETED_TEST" ) );
1513
+ }
1514
+
1515
+ delete_user_meta( $user->ID, 'test_2FA' );
1516
+ $this->mo_auth_show_success_message();
1517
 
 
 
 
 
 
 
 
1518
  } else {
1519
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
1520
+ $this->mo_auth_show_error_message();
1521
  }
1522
 
 
 
 
 
 
 
1523
  }
 
1524
  }
1525
  }
1526
 
1527
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_out_of_band_success' ) {
1528
+ $nonce = $_POST['mo2f_out_of_band_success_nonce'];
1529
+
1530
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-out-of-band-success-nonce' ) ) {
1531
+ $error = new WP_Error();
1532
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1533
 
1534
+ return $error;
1535
+ } else {
1536
+ $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
1537
+ $mo2f_EmailVerification_config_status = $Mo2fdbQueries->get_user_detail( 'mo2f_EmailVerification_config_status', $user->ID );
1538
+ if ( ! current_user_can( 'manage_options' ) && $mo2f_configured_2FA_method == 'OUT OF BAND EMAIL' ) {
1539
+ if ( $mo2f_EmailVerification_config_status ) {
1540
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1541
+ } else {
1542
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1543
+ $enduser = new Two_Factor_Setup();
1544
+ $response = json_decode( $enduser->mo2f_update_userinfo( $email, $mo2f_configured_2FA_method, null, null, null ), true );
1545
+ update_option( 'mo2f_message', '<b> ' . Mo2fConstants:: langTranslate( "EMAIL_VERFI" ) . '</b> ' . Mo2fConstants:: langTranslate( "SET_AS_2ND_FACTOR" ) );
1546
+ }
1547
  } else {
1548
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
 
 
 
1549
  }
1550
+ delete_user_meta( $user->ID, 'test_2FA' );
1551
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
1552
+ 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS',
1553
+ 'mo2f_EmailVerification_config_status' => true
1554
+ ) );
 
 
 
1555
 
1556
+ $this->mo_auth_show_success_message();
1557
+ }
1558
 
1559
 
1560
  }
1561
 
1562
  if ( isset( $_POST['option'] ) and $_POST['option'] == 'mo2f_out_of_band_error' ) { //push and out of band email denied
1563
+ $nonce = $_POST['mo2f_out_of_band_error_nonce'];
1564
+
1565
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-out-of-band-error-nonce' ) ) {
1566
+ $error = new WP_Error();
1567
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1568
+
1569
+ return $error;
1570
+ } else {
1571
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "DENIED_REQUEST" ) );
1572
+ delete_user_meta( $user->ID, 'test_2FA' );
1573
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
1574
+ 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS',
1575
+ 'mo2f_EmailVerification_config_status' => true
1576
+ ) );
1577
+ $this->mo_auth_show_error_message();
1578
+ }
1579
 
1580
  }
1581
 
1582
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_google_authy_test' ) {
1583
+
1584
+ $nonce = $_POST['mo2f_validate_google_authy_test_nonce'];
1585
+
1586
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-validate-google-authy-test-nonce' ) ) {
1587
+ $error = new WP_Error();
1588
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1589
 
1590
+ return $error;
 
 
 
 
 
1591
  } else {
1592
+ $otp_token = '';
1593
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
1594
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ENTER_VALUE" ) );
1595
+ $this->mo_auth_show_error_message();
1596
+
1597
+ return;
1598
+ } else {
1599
+ $otp_token = sanitize_text_field( $_POST['otp_token'] );
1600
+ }
1601
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1602
+ $customer = new Customer_Setup();
1603
+ $content = json_decode( $customer->validate_otp_token( 'GOOGLE AUTHENTICATOR', $email, null, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1604
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1605
 
1606
+ if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //Google OTP validated
1607
 
1608
+ if ( current_user_can( 'manage_options' ) ) {
1609
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1610
+ } else {
1611
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1612
+ }
1613
 
1614
+ delete_user_meta( $user->ID, 'test_2FA' );
1615
+ $this->mo_auth_show_success_message();
1616
 
1617
 
1618
+ } else { // OTP Validation failed.
1619
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
1620
+ $this->mo_auth_show_error_message();
1621
+
1622
+ }
1623
+ } else {
1624
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_VALIDATING_OTP" ) );
1625
  $this->mo_auth_show_error_message();
1626
 
1627
  }
 
 
 
 
1628
  }
1629
  }
1630
 
1631
+ if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_google_appname' ) {
1632
+ $nonce = $_POST['mo2f_google_appname_nonce'];
1633
+
1634
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-google-appname-nonce' ) ) {
1635
+ $error = new WP_Error();
1636
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1637
+
1638
+ return $error;
1639
+ } else {
1640
+
1641
+ update_option('mo2f_google_appname',((isset($_POST['mo2f_google_auth_appname']) && $_POST['mo2f_google_auth_appname']!='') ? $_POST['mo2f_google_auth_appname'] : 'miniOrangeAuth'));
1642
+ }
1643
+
1644
+ }
1645
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_google_authenticator_validate' ) {
1646
+ $nonce = $_POST['mo2f_configure_google_authenticator_validate_nonce'];
1647
+
1648
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-configure-google-authenticator-validate-nonce' ) ) {
1649
+ $error = new WP_Error();
1650
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1651
+
1652
+ return $error;
1653
+ } else {
1654
+ $otpToken = $_POST['google_token'];
1655
+ $ga_secret = isset( $_POST['google_auth_secret'] ) ? $_POST['google_auth_secret'] : null;
1656
+ if ( MO2f_Utility::mo2f_check_number_length( $otpToken ) ) {
1657
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1658
+ $google_auth = new Miniorange_Rba_Attributes();
1659
+ $google_response = json_decode( $google_auth->mo2f_validate_google_auth( $email, $otpToken, $ga_secret ), true );
1660
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1661
+ if ( $google_response['status'] == 'SUCCESS' ) {
1662
+ $enduser = new Two_Factor_Setup();
1663
+ $response = json_decode( $enduser->mo2f_update_userinfo( $email, "GOOGLE AUTHENTICATOR", null, null, null ), true );
1664
 
1665
 
1666
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1667
 
1668
+ if ( $response['status'] == 'SUCCESS' ) {
1669
 
1670
+ delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
1671
 
1672
+ delete_user_meta( $user->ID, 'configure_2FA' );
1673
 
1674
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
1675
+ 'mo2f_GoogleAuthenticator_config_status' => true,
1676
+ 'mo2f_AuthyAuthenticator_config_status' => false,
1677
+ 'mo2f_configured_2FA_method' => "Google Authenticator",
1678
+ 'user_registration_with_miniorange' => 'SUCCESS',
1679
+ 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS'
1680
+ ) );
1681
 
1682
+ update_user_meta( $user->ID, 'mo2f_external_app_type', "Google Authenticator" );
1683
+ mo2f_display_test_2fa_notification($user);
1684
 
1685
+ } else {
1686
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1687
+ $this->mo_auth_show_error_message();
1688
+
1689
+ }
1690
  } else {
1691
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1692
  $this->mo_auth_show_error_message();
1693
 
1694
  }
1695
  } else {
1696
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_OTP_CAUSES" ) . '<br>1. ' . Mo2fConstants:: langTranslate( "INVALID_OTP" ) . '<br>2. ' . Mo2fConstants:: langTranslate( "APP_TIME_SYNC" ) );
1697
  $this->mo_auth_show_error_message();
1698
 
1699
  }
1700
  } else {
1701
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_VALIDATING_USER" ) );
1702
  $this->mo_auth_show_error_message();
1703
 
1704
  }
1705
  } else {
1706
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ONLY_DIGITS_ALLOWED" ) );
1707
  $this->mo_auth_show_error_message();
1708
 
1709
  }
 
 
 
 
1710
  }
1711
  }
1712
 
1713
 
1714
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_authy_authenticator' ) {
1715
+ $nonce = $_POST['mo2f_configure_authy_authenticator_nonce'];
1716
+
1717
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-configure-authy-authenticator-nonce' ) ) {
1718
+ $error = new WP_Error();
1719
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1720
+
1721
+ return $error;
1722
+ } else {
1723
+ $authy = new Miniorange_Rba_Attributes();
1724
+ $user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1725
+ $authy_response = json_decode( $authy->mo2f_google_auth_service( $user_email ), true );
1726
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1727
+ if ( $authy_response['status'] == 'SUCCESS' ) {
1728
+ $mo2f_authy_keys = array();
1729
+ $mo2f_authy_keys['authy_qrCode'] = $authy_response['qrCodeData'];
1730
+ $mo2f_authy_keys['mo2f_authy_secret'] = $authy_response['secret'];
1731
+ $_SESSION['mo2f_authy_keys'] = $mo2f_authy_keys;
1732
+ } else {
1733
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_USER_REGISTRATION" ) );
1734
+ $this->mo_auth_show_error_message();
1735
+ }
1736
  } else {
1737
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_USER_REGISTRATION" ) );
1738
  $this->mo_auth_show_error_message();
1739
  }
 
 
 
1740
  }
1741
  }
1742
 
1743
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_authy_authenticator_validate' ) {
1744
+ $nonce = $_POST['mo2f_configure_authy_authenticator_validate_nonce'];
1745
+
1746
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-configure-authy-authenticator-validate-nonce' ) ) {
1747
+ $error = new WP_Error();
1748
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1749
+
1750
+ return $error;
1751
+ } else {
1752
+ $otpToken = $_POST['mo2f_authy_token'];
1753
+ $authy_secret = isset( $_POST['mo2f_authy_secret'] ) ? $_POST['mo2f_authy_secret'] : null;
1754
+ if ( MO2f_Utility::mo2f_check_number_length( $otpToken ) ) {
1755
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1756
+ $authy_auth = new Miniorange_Rba_Attributes();
1757
+ $authy_response = json_decode( $authy_auth->mo2f_validate_google_auth( $email, $otpToken, $authy_secret ), true );
1758
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1759
+ if ( $authy_response['status'] == 'SUCCESS' ) {
1760
+ $enduser = new Two_Factor_Setup();
1761
+ $response = json_decode( $enduser->mo2f_update_userinfo( $email, 'GOOGLE AUTHENTICATOR', null, null, null ), true );
1762
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1763
 
1764
+ if ( $response['status'] == 'SUCCESS' ) {
1765
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
1766
+ 'mo2f_GoogleAuthenticator_config_status' => false,
1767
+ 'mo2f_AuthyAuthenticator_config_status' => true,
1768
+ 'mo2f_configured_2FA_method' => "Authy Authenticator",
1769
+ 'user_registration_with_miniorange' => 'SUCCESS',
1770
+ 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS'
1771
+ ) );
1772
+ update_user_meta( $user->ID, 'mo2f_external_app_type', "Authy Authenticator" );
1773
+ delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
1774
+ delete_user_meta( $user->ID, 'configure_2FA' );
1775
+
1776
+ mo2f_display_test_2fa_notification($user);
1777
 
1778
+ } else {
1779
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1780
+ $this->mo_auth_show_error_message();
1781
+ }
1782
  } else {
1783
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1784
  $this->mo_auth_show_error_message();
1785
  }
1786
  } else {
1787
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_OTP_CAUSES" ) . '<br>1. ' . Mo2fConstants:: langTranslate( "INVALID_OTP" ) . '<br>2. ' . Mo2fConstants:: langTranslate( "APP_TIME_SYNC" ) );
1788
  $this->mo_auth_show_error_message();
1789
  }
1790
  } else {
1791
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_VALIDATING_USER" ) );
1792
  $this->mo_auth_show_error_message();
1793
  }
1794
  } else {
1795
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ONLY_DIGITS_ALLOWED" ) );
1796
  $this->mo_auth_show_error_message();
1797
  }
 
 
 
1798
  }
1799
  }
1800
 
1801
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_kba' ) {
1802
+
1803
+ $nonce = $_POST['mo2f_save_kba_nonce'];
1804
+
1805
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-save-kba-nonce' ) ) {
1806
+ $error = new WP_Error();
1807
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1808
+
1809
+ return $error;
1810
+ } else {
1811
+
1812
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kbaquestion_1'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kba_ans1'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kbaquestion_2'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kba_ans2'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kbaquestion_3'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_kba_ans3'] ) ) {
1813
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1814
+ $this->mo_auth_show_error_message();
1815
 
1816
 
1817
+ return;
1818
+ }
1819
 
1820
+ $kba_q1 = $_POST['mo2f_kbaquestion_1'];
1821
+ $kba_a1 = sanitize_text_field( $_POST['mo2f_kba_ans1'] );
1822
+ $kba_q2 = $_POST['mo2f_kbaquestion_2'];
1823
+ $kba_a2 = sanitize_text_field( $_POST['mo2f_kba_ans2'] );
1824
+ $kba_q3 = sanitize_text_field( $_POST['mo2f_kbaquestion_3'] );
1825
+ $kba_a3 = sanitize_text_field( $_POST['mo2f_kba_ans3'] );
1826
 
1827
 
1828
+ if ( strcasecmp( $kba_q1, $kba_q2 ) == 0 || strcasecmp( $kba_q2, $kba_q3 ) == 0 || strcasecmp( $kba_q3, $kba_q1 ) == 0 ) {
1829
+ update_option( 'mo2f_message', 'The questions you select must be unique.' );
1830
+ $this->mo_auth_show_error_message();
1831
 
1832
 
1833
+ return;
1834
+ }
1835
+ $kba_q1 = addcslashes( stripslashes( $kba_q1 ), '"\\' );
1836
+ $kba_a1 = addcslashes( stripslashes( $kba_a1 ), '"\\' );
1837
+ $kba_q2 = addcslashes( stripslashes( $kba_q2 ), '"\\' );
1838
+ $kba_a2 = addcslashes( stripslashes( $kba_a2 ), '"\\' );
1839
+ $kba_q3 = addcslashes( stripslashes( $kba_q3 ), '"\\' );
1840
+ $kba_a3 = addcslashes( stripslashes( $kba_a3 ), '"\\' );
1841
+
1842
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1843
+ $kba_registration = new Two_Factor_Setup();
1844
+ $kba_reg_reponse = json_decode( $kba_registration->register_kba_details( $email, $kba_q1, $kba_a1, $kba_q2, $kba_a2, $kba_q3, $kba_a3 ), true );
1845
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1846
+ if ( $kba_reg_reponse['status'] == 'SUCCESS' ) {
1847
+ if ( isset( $_POST['mobile_kba_option'] ) && $_POST['mobile_kba_option'] == 'mo2f_request_for_kba_as_emailbackup' ) {
1848
+ MO2f_Utility::unset_session_variables( 'mo2f_mobile_support' );
1849
 
1850
+ delete_user_meta( $user->ID, 'configure_2FA' );
1851
+ delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
 
 
 
 
 
1852
 
1853
+ $message = mo2f_lt( 'Your KBA as alternate 2 factor is configured successfully.' );
1854
+ update_option( 'mo2f_message', $message );
1855
+ $this->mo_auth_show_success_message();
1856
 
1857
+ } else {
1858
+ $enduser = new Two_Factor_Setup();
1859
+ $response = json_decode( $enduser->mo2f_update_userinfo( $email, 'KBA', null, null, null ), true );
1860
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1861
+ if ( $response['status'] == 'ERROR' ) {
1862
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1863
+ $this->mo_auth_show_error_message();
1864
 
1865
+ } else if ( $response['status'] == 'SUCCESS' ) {
1866
+ delete_user_meta( $user->ID, 'configure_2FA' );
 
 
 
 
 
1867
 
1868
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
1869
+ 'mo2f_SecurityQuestions_config_status' => true,
1870
+ 'mo2f_configured_2FA_method' => "Security Questions",
1871
+ 'mo_2factor_user_registration_status' => "MO_2_FACTOR_PLUGIN_SETTINGS"
1872
+ ) );
1873
 
1874
+ mo2f_display_test_2fa_notification($user);
 
 
 
 
1875
 
1876
+ } else {
1877
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1878
+ $this->mo_auth_show_error_message();
1879
 
1880
+ }
1881
  } else {
1882
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1883
  $this->mo_auth_show_error_message();
1884
 
1885
  }
 
 
 
 
1886
  }
1887
+ } else {
1888
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_KBA" ) );
1889
+ $this->mo_auth_show_error_message();
1890
+
1891
+
1892
+ return;
1893
  }
1894
  } else {
1895
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_KBA" ) );
1898
 
1899
  return;
1900
  }
 
 
 
 
 
 
1901
  }
1902
 
1903
  }
1904
 
1905
 
1906
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_kba_details' ) {
1907
+
1908
+ $nonce = $_POST['mo2f_validate_kba_details_nonce'];
1909
+
1910
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-validate-kba-details-nonce' ) ) {
1911
+ $error = new WP_Error();
1912
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1913
+
1914
+ return $error;
1915
+ } else {
1916
+
1917
+ $kba_ans_1 = '';
1918
+ $kba_ans_2 = '';
1919
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_answer_1'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_answer_1'] ) ) {
1920
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1921
+ $this->mo_auth_show_error_message();
1922
 
1923
+ return;
1924
+ } else {
1925
+ $kba_ans_1 = sanitize_text_field( $_POST['mo2f_answer_1'] );
1926
+ $kba_ans_2 = sanitize_text_field( $_POST['mo2f_answer_2'] );
1927
+ }
 
 
 
 
 
 
1928
 
1929
+ //if the php session folder has insufficient permissions, temporary options to be used
1930
+ $kba_questions = isset( $_SESSION['mo_2_factor_kba_questions'] ) && ! empty( $_SESSION['mo_2_factor_kba_questions'] ) ? $_SESSION['mo_2_factor_kba_questions'] : get_option( 'kba_questions' );
1931
 
1932
+ $kbaAns = array();
1933
+ $kbaAns[0] = $kba_questions[0];
1934
+ $kbaAns[1] = $kba_ans_1;
1935
+ $kbaAns[2] = $kba_questions[1];
1936
+ $kbaAns[3] = $kba_ans_2;
1937
 
1938
+ //if the php session folder has insufficient permissions, temporary options to be used
1939
+ $mo2f_transactionId = isset( $_SESSION['mo2f_transactionId'] ) && ! empty( $_SESSION['mo2f_transactionId'] ) ? $_SESSION['mo2f_transactionId'] : get_option( 'mo2f_transactionId' );
1940
 
1941
+ $kba_validate = new Customer_Setup();
1942
+ $kba_validate_response = json_decode( $kba_validate->validate_otp_token( 'KBA', null, $mo2f_transactionId, $kbaAns, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1943
 
1944
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1945
+ if ( strcasecmp( $kba_validate_response['status'], 'SUCCESS' ) == 0 ) {
1946
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
1947
+ delete_user_meta( $user->ID, 'test_2FA' );
1948
+ $this->mo_auth_show_success_message();
1949
 
1950
+ } else { // KBA Validation failed.
1951
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ANSWERS" ) );
1952
+ $this->mo_auth_show_error_message();
1953
 
1954
+ }
1955
  }
1956
  }
1957
  }
1958
 
1959
 
1960
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_otp_over_sms_send_otp' ) { // sendin otp for configuring OTP over SMS
1961
+
1962
+ $nonce = $_POST['mo2f_configure_otp_over_sms_send_otp_nonce'];
1963
+
1964
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-configure-otp-over-sms-send-otp-nonce' ) ) {
1965
+ $error = new WP_Error();
1966
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1967
 
1968
+ return $error;
1969
+ } else {
1970
+ $phone = sanitize_text_field( $_POST['verify_phone'] );
1971
 
1972
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $phone ) ) {
1973
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1974
+ $this->mo_auth_show_error_message();
1975
+
1976
+ return;
1977
+ }
1978
 
1979
+ $phone = str_replace( ' ', '', $phone );
1980
+ $_SESSION['user_phone'] = $phone;
1981
+ update_option( 'user_phone_temp', $phone );
1982
+ $customer = new Customer_Setup();
1983
+ $currentMethod = "SMS";
1984
 
1985
+ $content = json_decode( $customer->send_otp_token( $phone, $currentMethod, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1986
+
1987
+ if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate otp token */
1988
+ if ( $content['status'] == 'ERROR' ) {
1989
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1990
+ $this->mo_auth_show_error_message();
1991
+ } else if ( $content['status'] == 'SUCCESS' ) {
1992
+ $_SESSION['mo2f_transactionId'] = $content['txId'];
1993
+ update_option( 'mo2f_transactionId', $content['txId'] );
1994
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "OTP_SENT" ) . ' ' . $phone . ' .' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
1995
+ update_option( 'mo2f_number_of_transactions', get_option( 'mo2f_number_of_transactions' ) - 1 );
1996
+ $this->mo_auth_show_success_message();
1997
+ } else {
1998
+ update_option( 'mo2f_message', Mo2fConstants::langTranslate( $content['message'] ) );
1999
+ $this->mo_auth_show_error_message();
2000
+ }
2001
 
 
 
 
 
 
 
 
 
 
 
2002
  } else {
2003
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
2004
  $this->mo_auth_show_error_message();
2005
  }
 
 
 
 
2006
  }
2007
  }
2008
 
2009
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_otp_over_sms_validate' ) {
2010
+ $nonce = $_POST['mo2f_configure_otp_over_sms_validate_nonce'];
2011
+
2012
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-configure-otp-over-sms-validate-nonce' ) ) {
2013
+ $error = new WP_Error();
2014
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
2015
 
2016
+ return $error;
2017
+ } else {
2018
+ $otp_token = '';
2019
+ if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['otp_token'] ) ) {
2020
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
2021
+ $this->mo_auth_show_error_message();
2022
+
2023
+ return;
2024
+ } else {
2025
+ $otp_token = sanitize_text_field( $_POST['otp_token'] );
2026
+ }
2027
 
2028
+ //if the php session folder has insufficient permissions, temporary options to be used
2029
+ $mo2f_transactionId = isset( $_SESSION['mo2f_transactionId'] ) && ! empty( $_SESSION['mo2f_transactionId'] ) ? $_SESSION['mo2f_transactionId'] : get_option( 'mo2f_transactionId' );
2030
+ $user_phone = isset( $_SESSION['user_phone'] ) && $_SESSION['user_phone'] != 'false' ? $_SESSION['user_phone'] : get_option( 'user_phone_temp' );
2031
+ $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
2032
+ $phone = $Mo2fdbQueries->get_user_detail( 'mo2f_user_phone', $user->ID );
2033
+ $customer = new Customer_Setup();
2034
+ $content = json_decode( $customer->validate_otp_token( $mo2f_configured_2FA_method, null, $mo2f_transactionId, $otp_token, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
2035
 
2036
+ if ( $content['status'] == 'ERROR' ) {
2037
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $content['message'] ) );
2038
 
2039
+ } else if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) { //OTP validated
2040
+ if ( $phone && strlen( $phone ) >= 4 ) {
2041
+ if ( $user_phone != $phone ) {
2042
+ $Mo2fdbQueries->update_user_details( $user->ID, array( 'mobile_registration_status' => false ) );
2043
 
2044
+ }
2045
  }
2046
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
 
2047
 
2048
+ $enduser = new Two_Factor_Setup();
2049
+ $TwoFA_method_to_configure = get_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', true );
2050
+ $current_method = MO2f_Utility::mo2f_decode_2_factor( $TwoFA_method_to_configure, "server" );
2051
+ $response = json_decode( $enduser->mo2f_update_userinfo( $email, $current_method, $user_phone, null, null ), true );
2052
 
2053
+ if ( json_last_error() == JSON_ERROR_NONE ) {
2054
 
2055
+ if ( $response['status'] == 'ERROR' ) {
2056
+ MO2f_Utility::unset_session_variables( 'user_phone' );
2057
+ delete_option( 'user_phone_temp' );
2058
 
2059
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
2060
+ $this->mo_auth_show_error_message();
2061
+ } else if ( $response['status'] == 'SUCCESS' ) {
2062
+
2063
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
2064
+ 'mo2f_configured_2FA_method' => 'OTP Over SMS',
2065
+ 'mo2f_OTPOverSMS_config_status' => true,
2066
+ 'user_registration_with_miniorange' => 'SUCCESS',
2067
+ 'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS',
2068
+ 'mo2f_user_phone' => $user_phone
2069
+ ) );
2070
 
2071
+ delete_user_meta( $user->ID, 'configure_2FA' );
2072
+ delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
2073
 
2074
+ unset( $_SESSION['user_phone'] );
2075
+ MO2f_Utility::unset_session_variables( 'user_phone' );
2076
+ delete_option( 'user_phone_temp' );
2077
 
2078
+ mo2f_display_test_2fa_notification($user);
2079
+ } else {
2080
+ MO2f_Utility::unset_session_variables( 'user_phone' );
2081
+ delete_option( 'user_phone_temp' );
2082
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
2083
+ $this->mo_auth_show_error_message();
2084
+ }
2085
  } else {
2086
  MO2f_Utility::unset_session_variables( 'user_phone' );
2087
  delete_option( 'user_phone_temp' );
2088
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
2089
  $this->mo_auth_show_error_message();
2090
  }
2091
+
2092
+ } else { // OTP Validation failed.
2093
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_OTP" ) );
 
2094
  $this->mo_auth_show_error_message();
2095
  }
 
 
 
 
2096
  }
2097
 
2098
  }
2100
  // user clicks on Set 2-Factor method
2101
  if ( ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_free_plan_auth_methods' ) ||
2102
  ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_standard_plan_auth_methods' ) ) {
2103
+
2104
+ $nonce = $_POST['miniorange_save_form_auth_methods_nonce'];
2105
+
2106
+ if ( ! wp_verify_nonce( $nonce, 'miniorange-save-form-auth-methods-nonce' ) ) {
2107
+ $error = new WP_Error();
2108
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
2109
+
2110
+ return $error;
2111
+ } else {
2112
  $is_customer_registered = $Mo2fdbQueries->get_user_detail( 'user_registration_with_miniorange', $user->ID ) == 'SUCCESS' ? true : false;
2113
 
2114
  $selected_2FA_method = MO2f_Utility::mo2f_decode_2_factor( isset( $_POST['mo2f_configured_2FA_method_free_plan'] ) ? $_POST['mo2f_configured_2FA_method_free_plan'] : $_POST['mo2f_selected_action_standard_plan'], "wpdb" );
2142
  "miniOrange Soft Token",
2143
  "Authy Authenticator"
2144
  ) ) ) {
2145
+
2146
  } else {
2147
  update_option( 'mo2f_enable_2fa_prompt_on_login_page', 0 );
2148
  }
2165
 
2166
  display_customer_registration_forms( $user );
2167
  }
2168
+ }
2169
  }
2170
 
2171
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_enable_2FA_for_users_option' ) {
2172
+ $nonce = $_POST['mo2f_enable_2FA_for_users_option_nonce'];
2173
+
2174
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-enable-2FA-for-users-option-nonce' ) ) {
2175
+ $error = new WP_Error();
2176
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
2177
+
2178
+ return $error;
2179
+ } else {
2180
+ update_option( 'mo2f_enable_2fa_for_users', isset( $_POST['mo2f_enable_2fa_for_users'] ) ? $_POST['mo2f_enable_2fa_for_users'] : 0 );
2181
+ }
2182
  }
2183
 
2184
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_disable_proxy_setup_option' ) {
2185
+ $nonce = $_POST['mo2f_disable_proxy_setup_option_nonce'];
2186
+
2187
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-disable-proxy-setup-option-nonce' ) ) {
2188
+ $error = new WP_Error();
2189
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
2190
+
2191
+ return $error;
2192
+ } else {
2193
+ delete_option( 'mo2f_proxy_host' );
2194
+ delete_option( 'mo2f_port_number' );
2195
+ delete_option( 'mo2f_proxy_username' );
2196
+ delete_option( 'mo2f_proxy_password' );
2197
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "Proxy Configurations Reset." ) );
2198
+ $this->mo_auth_show_success_message();
2199
+ }
2200
  }
2201
 
2202
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_enable_2FA_option' ) {
2203
+ $nonce = $_POST['mo2f_enable_2FA_option_nonce'];
2204
+
2205
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-enable-2FA-option-nonce' ) ) {
2206
+ $error = new WP_Error();
2207
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
2208
+
2209
+ return $error;
2210
+ } else {
2211
+ update_option( 'mo2f_enable_2fa', isset( $_POST['mo2f_enable_2fa'] ) ? $_POST['mo2f_enable_2fa'] : 0 );
2212
+ }
2213
  }
2214
 
2215
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_enable_2FA_on_login_page_option' ) {
2216
+ $nonce = $_POST['mo2f_enable_2FA_on_login_page_option_nonce'];
2217
+
2218
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-enable-2FA-on-login-page-option-nonce' ) ) {
2219
+ $error = new WP_Error();
2220
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
2221
+
2222
+ return $error;
2223
+ } else {
2224
+ update_option( 'mo2f_enable_2fa_prompt_on_login_page', isset( $_POST['mo2f_enable_2fa_prompt_on_login_page'] ) ? $_POST['mo2f_enable_2fa_prompt_on_login_page'] : 0 );
2225
+ }
2226
  }
2227
 
2228
 
2229
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo_2factor_test_authentication_method' ) {
2230
+
2231
+ $nonce = $_POST['mo_2factor_test_authentication_method_nonce'];
2232
+
2233
+ if ( ! wp_verify_nonce( $nonce, 'mo-2factor-test-authentication-method-nonce' ) ) {
2234
+ $error = new WP_Error();
2235
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
2236
 
2237
+ return $error;
2238
+ } else {
2239
+ update_user_meta( $user->ID, 'test_2FA', 1 );
2240
 
2241
 
2242
+ $selected_2FA_method = $_POST['mo2f_configured_2FA_method_test'];
2243
+ $selected_2FA_method_server = MO2f_Utility::mo2f_decode_2_factor( $selected_2FA_method, "server" );
2244
+ $customer = new Customer_Setup();
2245
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
2246
+ $customer_key = get_option( 'mo2f_customerKey' );
2247
+ $api_key = get_option( 'mo2f_api_key' );
2248
 
2249
+ if ( $selected_2FA_method == 'Security Questions' ) {
2250
+ $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
2251
 
2252
+ if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate KBA Questions*/
2253
+ if ( $response['status'] == 'SUCCESS' ) {
2254
+ $_SESSION['mo2f_transactionId'] = $response['txId'];
2255
+ update_option( 'mo2f_transactionId', $response['txId'] );
2256
+ $questions = array();
2257
+ $questions[0] = $response['questions'][0]['question'];
2258
+ $questions[1] = $response['questions'][1]['question'];
2259
+ $_SESSION['mo_2_factor_kba_questions'] = $questions;
2260
+ update_option( 'kba_questions', $questions );
2261
 
2262
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ANSWER_SECURITY_QUESTIONS" ) );
2263
+ $this->mo_auth_show_success_message();
2264
 
2265
+ } else if ( $response['status'] == 'ERROR' ) {
2266
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_FETCHING_QUESTIONS" ) );
2267
+ $this->mo_auth_show_error_message();
2268
+
2269
+ }
2270
+ } else {
2271
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_FETCHING_QUESTIONS" ) );
2272
  $this->mo_auth_show_error_message();
2273
 
2274
  }
 
 
 
 
 
2275
 
2276
+ } else if ( $selected_2FA_method == 'miniOrange Push Notification' ) {
2277
+ $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
2278
+ if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate Qr code */
2279
+ if ( $response['status'] == 'ERROR' ) {
2280
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
2281
+ $this->mo_auth_show_error_message();
 
 
 
 
 
 
 
 
 
2282
 
2283
  } else {
2284
+ if ( $response['status'] == 'SUCCESS' ) {
2285
+ $_SESSION['mo2f_transactionId'] = $response['txId'];
2286
+ update_option( 'mo2f_transactionId', $response['txId'] );
2287
+ $_SESSION['mo2f_show_qr_code'] = 'MO_2_FACTOR_SHOW_QR_CODE';
2288
+ update_option( 'mo2f_transactionId', $response['txId'] );
2289
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "PUSH_NOTIFICATION_SENT" ) );
2290
+ $this->mo_auth_show_success_message();
2291
 
2292
+ } else {
2293
+ $session_variables = array( 'mo2f_qrCode', 'mo2f_transactionId', 'mo2f_show_qr_code' );
2294
+ MO2f_Utility::unset_session_variables( $session_variables );
2295
 
2296
+ delete_option( 'mo2f_transactionId' );
2297
+ update_option( 'mo2f_message', 'An error occurred while processing your request. Please Try again.' );
2298
+ $this->mo_auth_show_error_message();
 
 
2299
 
2300
+ }
2301
+ }
2302
+ } else {
2303
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
2304
+ $this->mo_auth_show_error_message();
 
 
2305
 
2306
+ }
2307
+ } else if ( $selected_2FA_method == 'OTP Over SMS' ) {
2308
+ $phone = $Mo2fdbQueries->get_user_detail( 'mo2f_user_phone', $user->ID );
2309
+ $response = json_decode( $customer->send_otp_token( $phone, $selected_2FA_method_server, $customer_key, $api_key ), true );
2310
+ if ( strcasecmp( $response['status'], 'SUCCESS' ) == 0 ) {
2311
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "OTP_SENT" ) . ' <b>' . ( $phone ) . '</b>. ' . Mo2fConstants:: langTranslate( "ENTER_OTP" ) );
2312
+ update_option( 'mo2f_number_of_transactions', get_option( 'mo2f_number_of_transactions' ) - 1 );
2313
 
2314
+ $_SESSION['mo2f_transactionId'] = $response['txId'];
2315
+ update_option( 'mo2f_transactionId', $response['txId'] );
2316
+ $this->mo_auth_show_success_message();
2317
 
2318
+ } else {
2319
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_IN_SENDING_OTP" ) );
2320
+ $this->mo_auth_show_error_message();
2321
 
2322
+ }
2323
+ } else if ( $selected_2FA_method == 'miniOrange QR Code Authentication' ) {
2324
+ $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
2325
 
2326
+ if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate Qr code */
 
 
2327
 
2328
+ if ( $response['status'] == 'ERROR' ) {
2329
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
2330
+ $this->mo_auth_show_error_message();
 
 
 
 
2331
 
2332
  } else {
2333
+ if ( $response['status'] == 'SUCCESS' ) {
2334
+ $_SESSION['mo2f_qrCode'] = $response['qrCode'];
2335
+ $_SESSION['mo2f_transactionId'] = $response['txId'];
2336
+ $_SESSION['mo2f_show_qr_code'] = 'MO_2_FACTOR_SHOW_QR_CODE';
2337
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "SCAN_QR_CODE" ) );
2338
+ $this->mo_auth_show_success_message();
2339
+
2340
+ } else {
2341
+ unset( $_SESSION['mo2f_qrCode'] );
2342
+ unset( $_SESSION['mo2f_transactionId'] );
2343
+ unset( $_SESSION['mo2f_show_qr_code'] );
2344
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
2345
+ $this->mo_auth_show_error_message();
2346
 
2347
+ }
2348
  }
2349
+ } else {
2350
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
2351
+ $this->mo_auth_show_error_message();
 
2352
 
2353
+ }
2354
+ } else if ( $selected_2FA_method == 'Email Verification' ) {
2355
+ $this->miniorange_email_verification_call( $user );
2356
  }
 
 
 
2357
 
2358
 
2359
+ update_user_meta( $user->ID, 'mo2f_2FA_method_to_test', $selected_2FA_method );
2360
+ }
2361
 
2362
  }
2363
 
2364
  if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_go_back' ) {
2365
+ $nonce = $_POST['mo2f_go_back_nonce'];
2366
+
2367
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-go-back-nonce' ) ) {
2368
+ $error = new WP_Error();
2369
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
 
 
 
 
 
 
 
2370
 
2371
+ return $error;
2372
+ } else {
2373
+ $session_variables = array(
2374
+ 'mo2f_qrCode',
2375
+ 'mo2f_transactionId',
2376
+ 'mo2f_show_qr_code',
2377
+ 'user_phone',
2378
+ 'mo2f_google_auth',
2379
+ 'mo2f_mobile_support',
2380
+ 'mo2f_authy_keys'
2381
+ );
2382
+ MO2f_Utility::unset_session_variables( $session_variables );
2383
+ delete_option( 'mo2f_transactionId' );
2384
+ delete_option( 'user_phone_temp' );
2385
+
2386
+ delete_user_meta( $user->ID, 'test_2FA' );
2387
+ delete_user_meta( $user->ID, 'configure_2FA' );
2388
+ }
2389
  }
2390
 
2391
  }
2570
  global $Mo2fdbQueries;
2571
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
2572
  $google_auth = new Miniorange_Rba_Attributes();
2573
+
2574
+
2575
+ $gauth_name= get_option('mo2f_google_appname');
2576
+ $gauth_name = $gauth_name ? $gauth_name : 'miniOrangeAuth';
2577
+ $google_response = json_decode( $google_auth->mo2f_google_auth_service( $email,$gauth_name ), true );
2578
  if ( json_last_error() == JSON_ERROR_NONE ) {
2579
  if ( $google_response['status'] == 'SUCCESS' ) {
2580
  $mo2f_google_auth = array();
2764
  }
2765
 
2766
  function mo_auth_activate() {
2767
+
2768
+ $get_encryption_key = MO2f_Utility::random_str(40);
2769
+ update_option('mo2f_encryption_key',$get_encryption_key);
2770
+
2771
  if ( get_option( 'mo2f_customerKey' ) && ! get_option( 'mo2f_is_NC' ) ) {
2772
  update_option( 'mo2f_is_NC', 0 );
2773
  } else {
miniorange_2_factor_support.php CHANGED
@@ -52,6 +52,8 @@ function mo2f_support() {
52
  </div>
53
  <br>
54
  <input type="hidden" name="option" value="mo_2factor_send_query"/>
 
 
55
  <input type="submit" name="send_query" id="send_query"
56
  value="<?php echo mo2f_lt( 'Submit Query' ); ?>"
57
  style="float:right;" class="button button-primary button-large"/>
52
  </div>
53
  <br>
54
  <input type="hidden" name="option" value="mo_2factor_send_query"/>
55
+ <input type="hidden" name="mo_2factor_send_query_nonce"
56
+ value="<?php echo wp_create_nonce( "mo-2factor-send-query-nonce" ) ?>"/>
57
  <input type="submit" name="send_query" id="send_query"
58
  value="<?php echo mo2f_lt( 'Submit Query' ); ?>"
59
  style="float:right;" class="button button-primary button-large"/>
readme.txt CHANGED
@@ -5,7 +5,7 @@ Donate link: https://miniorange.com/
5
  Requires at least: 3.0.1
6
  Tested up to: 4.9.4
7
  Requires PHP: 5.3.0
8
- Stable tag: 5.1.8
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -222,8 +222,11 @@ miniOrange authentication service has 15+ authentication methods.One time passco
222
 
223
  == Changelog ==
224
 
 
 
 
225
  =5.1.8=
226
- * Google Authenticator-Two Factor Authentication (2FA) : Bug fix for Password Validation.
227
 
228
  =5.1.7=
229
  * Google Authenticator-Two Factor Authentication (2FA) : Bug fix for DB error after Update.
@@ -550,8 +553,11 @@ More descriptive setup messages and UI changes.
550
 
551
  == Upgrade Notice ==
552
 
 
 
 
553
  =5.1.8=
554
- * Google Authenticator-Two Factor Authentication (2FA) : Bug fix for Password Validation.
555
 
556
  =5.1.7=
557
  * Google Authenticator-Two Factor Authentication (2FA) : Bug fix for DB error after Update.
5
  Requires at least: 3.0.1
6
  Tested up to: 4.9.4
7
  Requires PHP: 5.3.0
8
+ Stable tag: 5.1.9
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
222
 
223
  == Changelog ==
224
 
225
+ =5.1.9=
226
+ * Google Authenticator-Two Factor Authentication (2FA) : Added visual tour and security fixes.
227
+
228
  =5.1.8=
229
+ * Google Authenticator-Two Factor Authentication (2FA) : Bug fix for Validation.
230
 
231
  =5.1.7=
232
  * Google Authenticator-Two Factor Authentication (2FA) : Bug fix for DB error after Update.
553
 
554
  == Upgrade Notice ==
555
 
556
+ =5.1.9=
557
+ * Google Authenticator-Two Factor Authentication (2FA) : Added visual tour and security fixes.
558
+
559
  =5.1.8=
560
+ * Google Authenticator-Two Factor Authentication (2FA) : Bug fix for Validation.
561
 
562
  =5.1.7=
563
  * Google Authenticator-Two Factor Authentication (2FA) : Bug fix for DB error after Update.
uninstall.php CHANGED
@@ -73,6 +73,9 @@ if ( ! is_multisite() ) {
73
  delete_option( 'mo2f_admin_company' );
74
  delete_option( 'mo2f_db_option_updated' );
75
  delete_option( 'mo2f_login_option_updated' );
 
 
 
76
  //delete all stored key-value pairs for the roles
77
  global $wp_roles;
78
  if ( ! isset( $wp_roles ) ) {
@@ -146,6 +149,8 @@ if ( ! is_multisite() ) {
146
  delete_option( 'mo2f_db_option_updated' );
147
  delete_option( 'mo2f_login_option_updated' );
148
  delete_option( 'mo2f_bug_fix_done' );
 
 
149
  //delete all stored key-value pairs for the roles
150
  global $wp_roles;
151
  if ( ! isset( $wp_roles ) ) {
73
  delete_option( 'mo2f_admin_company' );
74
  delete_option( 'mo2f_db_option_updated' );
75
  delete_option( 'mo2f_login_option_updated' );
76
+ delete_option( 'mo2f_encryption_key' );
77
+ delete_option( 'mo2f_google_appname' );
78
+
79
  //delete all stored key-value pairs for the roles
80
  global $wp_roles;
81
  if ( ! isset( $wp_roles ) ) {
149
  delete_option( 'mo2f_db_option_updated' );
150
  delete_option( 'mo2f_login_option_updated' );
151
  delete_option( 'mo2f_bug_fix_done' );
152
+ delete_option( 'mo2f_encryption_key' );
153
+ delete_option( 'mo2f_google_appname' );
154
  //delete all stored key-value pairs for the roles
155
  global $wp_roles;
156
  if ( ! isset( $wp_roles ) ) {
views/configure_authy_authenticator CHANGED
@@ -11,11 +11,16 @@
11
  <form name="f" method="post" id="mo2f_configure_google_authy_form1" action="">
12
  <input type="submit" name="mo2f_authy_configure" class="button button-primary button-large"
13
  style="width:45%;"
14
- value="<?php echo mo2f_lt( 'Configure' ); ?> "/><br><br>
 
 
 
15
  <input type="hidden" name="option" value="mo2f_configure_authy_authenticator"/>
16
  </form>
17
  <form name="f" method="post" action="" id="mo2f_go_back_form">
18
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
19
  <input type="submit" name="back" id="go_back" class="button button-primary button-large"
20
  style="width:45%;"
21
  value="<?php echo mo2f_lt( 'Back' ); ?>"/>
@@ -76,6 +81,8 @@
76
  value="<?php echo mo2f_lt( 'Verify and Save' ); ?>"/>
77
  <input type="hidden" name="mo2f_authy_secret" value="<?php echo $authy_secret; ?>"/>
78
  <input type="hidden" name="option" value="mo2f_configure_authy_authenticator_validate"/>
 
 
79
  </form>
80
  </div>
81
  </td>
11
  <form name="f" method="post" id="mo2f_configure_google_authy_form1" action="">
12
  <input type="submit" name="mo2f_authy_configure" class="button button-primary button-large"
13
  style="width:45%;"
14
+ value="<?php echo mo2f_lt( 'Configure' ); ?> "/>
15
+ <input type="hidden" name="mo2f_configure_authy_authenticator_nonce"
16
+ value="<?php echo wp_create_nonce( "mo2f-configure-authy-authenticator-nonce" ) ?>"/>
17
+ <br><br>
18
  <input type="hidden" name="option" value="mo2f_configure_authy_authenticator"/>
19
  </form>
20
  <form name="f" method="post" action="" id="mo2f_go_back_form">
21
  <input type="hidden" name="option" value="mo2f_go_back"/>
22
+ <input type="hidden" name="mo2f_go_back_nonce"
23
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
24
  <input type="submit" name="back" id="go_back" class="button button-primary button-large"
25
  style="width:45%;"
26
  value="<?php echo mo2f_lt( 'Back' ); ?>"/>
81
  value="<?php echo mo2f_lt( 'Verify and Save' ); ?>"/>
82
  <input type="hidden" name="mo2f_authy_secret" value="<?php echo $authy_secret; ?>"/>
83
  <input type="hidden" name="option" value="mo2f_configure_authy_authenticator_validate"/>
84
+ <input type="hidden" name="mo2f_configure_authy_authenticator_validate_nonce"
85
+ value="<?php echo wp_create_nonce( "mo2f-configure-authy-authenticator-validate-nonce" ) ?>"/>
86
  </form>
87
  </div>
88
  </td>
views/configure_google_authenticator CHANGED
@@ -5,7 +5,9 @@ function mo2f_configure_google_authenticator( $user ) {
5
  $data = isset( $_SESSION['mo2f_google_auth'] ) ? $mo2f_google_auth['ga_qrCode'] : null;
6
  $ga_secret = isset( $_SESSION['mo2f_google_auth'] ) ? $mo2f_google_auth['ga_secret'] : null;
7
  $h_size = 'h3';
8
-
 
 
9
  ?>
10
  <table>
11
  <tr>
@@ -25,7 +27,19 @@ function mo2f_configure_google_authenticator( $user ) {
25
  </li>
26
 
27
  </ol>
 
 
 
 
 
 
 
 
 
28
 
 
 
 
29
  <h4><?php echo mo2f_lt( 'Open Google Authenticator.' ); ?></h4>
30
  <ol>
31
  <li><?php echo mo2f_lt( 'In the app, tap on Menu and select "Set up account".' ); ?></li>
@@ -73,11 +87,7 @@ function mo2f_configure_google_authenticator( $user ) {
73
  </ol>
74
  </div>
75
  <br>
76
- <form name="f" method="post" action="" id="mo2f_go_back_form">
77
- <input type="hidden" name="option" value="mo2f_go_back"/>
78
- <input type="submit" name="back" id="go_back" class="button button-primary button-large"
79
- style="width:50px;" value="<?php echo mo2f_lt( 'Back' ); ?>"/>
80
- </form>
81
  </td>
82
  <td class="mo2f_vertical_line"></td>
83
  <td class="mo2f_google_authy_step3">
@@ -93,9 +103,18 @@ function mo2f_configure_google_authenticator( $user ) {
93
  style="width:95%;"/></span><br><br>
94
  <input type="hidden" name="google_auth_secret" value="<?php echo $ga_secret ?>"/>
95
  <input type="hidden" name="option" value="mo2f_configure_google_authenticator_validate"/>
 
 
96
  <input type="submit" name="validate" id="validate" class="button button-primary button-large"
97
- style="margin-left:12%;" value="<?php echo mo2f_lt( 'Verify and Save' ); ?>"/>
98
  </form>
 
 
 
 
 
 
 
99
  </div>
100
  </td>
101
  </tr>
5
  $data = isset( $_SESSION['mo2f_google_auth'] ) ? $mo2f_google_auth['ga_qrCode'] : null;
6
  $ga_secret = isset( $_SESSION['mo2f_google_auth'] ) ? $mo2f_google_auth['ga_secret'] : null;
7
  $h_size = 'h3';
8
+ $gauth_name= get_option('mo2f_google_appname');
9
+ $gauth_name = $gauth_name ? $gauth_name : 'miniOrangeAuth';
10
+
11
  ?>
12
  <table>
13
  <tr>
27
  </li>
28
 
29
  </ol>
30
+ <?php if(!(get_option( 'mo2f_is_NC' ) && ! get_option( 'mo2f_is_NNC' ))){?>
31
+ <h4>Choose your name on Google Authenicator:</h4>
32
+ <form name="f" id="login_settings_appname_form" method="post" action="">
33
+ <input type="hidden" name="option" value="mo2f_google_appname" />
34
+ <input type="hidden" name="mo2f_google_appname_nonce"
35
+ value="<?php echo wp_create_nonce( "mo2f-google-appname-nonce" ) ?>"/>
36
+ <input type="text" class="mo2f_table_textbox" style="width:27% !important;" name="mo2f_google_auth_appname" placeholder="Enter the app name" value="<?php echo $gauth_name;?>" />&nbsp;&nbsp;&nbsp;
37
+
38
+ <input type="submit" name="submit" value="Change App Name" class="button button-primary button-large" />
39
 
40
+ <br>
41
+ </form>
42
+ <?php }?>
43
  <h4><?php echo mo2f_lt( 'Open Google Authenticator.' ); ?></h4>
44
  <ol>
45
  <li><?php echo mo2f_lt( 'In the app, tap on Menu and select "Set up account".' ); ?></li>
87
  </ol>
88
  </div>
89
  <br>
90
+
 
 
 
 
91
  </td>
92
  <td class="mo2f_vertical_line"></td>
93
  <td class="mo2f_google_authy_step3">
103
  style="width:95%;"/></span><br><br>
104
  <input type="hidden" name="google_auth_secret" value="<?php echo $ga_secret ?>"/>
105
  <input type="hidden" name="option" value="mo2f_configure_google_authenticator_validate"/>
106
+ <input type="hidden" name="mo2f_configure_google_authenticator_validate_nonce"
107
+ value="<?php echo wp_create_nonce( "mo2f-configure-google-authenticator-validate-nonce" ) ?>"/>
108
  <input type="submit" name="validate" id="validate" class="button button-primary button-large"
109
+ style="margin-left:12%;margin-right:2%;float:left;" value="<?php echo mo2f_lt( 'Verify and Save' ); ?>"/>
110
  </form>
111
+ <form name="f" method="post" action="" id="mo2f_go_back_form">
112
+ <input type="hidden" name="option" value="mo2f_go_back"/>
113
+ <input type="submit" name="back" id="go_back" class="button button-primary button-large"
114
+ style="width:50px;float:left;" value="<?php echo mo2f_lt( 'Back' ); ?>"/>
115
+ <input type="hidden" name="mo2f_go_back_nonce"
116
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
117
+ </form>
118
  </div>
119
  </td>
120
  </tr>
views/configure_kba_questions CHANGED
@@ -162,6 +162,8 @@ function mo2f_configure_for_mobile_suppport_kba( $user ) {
162
  <?php mo2f_configure_kba_questions(); ?>
163
  <br>
164
  <input type="hidden" name="option" value="mo2f_save_kba"/>
 
 
165
  <table>
166
  <tr>
167
  <td>
@@ -175,7 +177,8 @@ function mo2f_configure_for_mobile_suppport_kba( $user ) {
175
 
176
  <form name="f" method="post" action="" id="mo2f_go_back_form">
177
  <input type="hidden" name="option" value="mo2f_go_back"/>
178
-
 
179
  <input type="submit" name="back" id="go_back" class="button button-primary button-large"
180
  value="<?php echo mo2f_lt( 'Back' ); ?>"
181
  style="width:100px;line-height:30px;"/>
162
  <?php mo2f_configure_kba_questions(); ?>
163
  <br>
164
  <input type="hidden" name="option" value="mo2f_save_kba"/>
165
+ <input type="hidden" name="mo2f_save_kba_nonce"
166
+ value="<?php echo wp_create_nonce( "mo2f-save-kba-nonce" ) ?>"/>
167
  <table>
168
  <tr>
169
  <td>
177
 
178
  <form name="f" method="post" action="" id="mo2f_go_back_form">
179
  <input type="hidden" name="option" value="mo2f_go_back"/>
180
+ <input type="hidden" name="mo2f_go_back_nonce"
181
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
182
  <input type="submit" name="back" id="go_back" class="button button-primary button-large"
183
  value="<?php echo mo2f_lt( 'Back' ); ?>"
184
  style="width:100px;line-height:30px;"/>
views/configure_miniorange_authenticator CHANGED
@@ -13,6 +13,8 @@
13
 
14
  <form name="f" method="post" action="">
15
  <input type="hidden" name="option" value="mo_auth_refresh_mobile_qrcode" />
 
 
16
  <?php if($mobile_reg_status) { ?>
17
  <div id="reconfigurePhone">
18
  <a data-toggle="collapse" href="#mo2f_show_download_app" aria-expanded="false">
@@ -48,6 +50,8 @@
48
  <br>
49
  <form name="f" method="post" action="" id="mo2f_go_back_form">
50
  <input type="hidden" name="option" value="mo2f_go_back" />
 
 
51
  </form>
52
  <script>
53
  jQuery('#go_back').click(function() {
@@ -156,13 +160,19 @@
156
  <div id="mobile_registered">
157
  <form name="f" method="post" id="mobile_register_form" action="" class="mo2f_display_none_forms">
158
  <input type="hidden" name="option" value="mo2f_configure_miniorange_authenticator_validate" />
 
 
159
  </form>
160
  </div>
161
  <form name="f" method="post" action="" id="mo2f_go_back_form" class="mo2f_display_none_forms">
162
  <input type="hidden" name="option" value="mo2f_go_back" />
 
 
163
  </form>
164
  <form name="f" method="post" id="mo2f_refresh_qr_form" action="" class="mo2f_display_none_forms">
165
  <input type="hidden" name="option" value="mo_auth_refresh_mobile_qrcode" />
 
 
166
  </form>
167
  <input type="button" name="back" id="back_to_methods" class="button button-primary button-large" value="<?php echo mo2f_lt('Back');?>" />
168
 
13
 
14
  <form name="f" method="post" action="">
15
  <input type="hidden" name="option" value="mo_auth_refresh_mobile_qrcode" />
16
+ <input type="hidden" name="mo_auth_refresh_mobile_qrcode_nonce"
17
+ value="<?php echo wp_create_nonce( "mo-auth-refresh-mobile-qrcode-nonce" ) ?>"/>
18
  <?php if($mobile_reg_status) { ?>
19
  <div id="reconfigurePhone">
20
  <a data-toggle="collapse" href="#mo2f_show_download_app" aria-expanded="false">
50
  <br>
51
  <form name="f" method="post" action="" id="mo2f_go_back_form">
52
  <input type="hidden" name="option" value="mo2f_go_back" />
53
+ <input type="hidden" name="mo2f_go_back_nonce"
54
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
55
  </form>
56
  <script>
57
  jQuery('#go_back').click(function() {
160
  <div id="mobile_registered">
161
  <form name="f" method="post" id="mobile_register_form" action="" class="mo2f_display_none_forms">
162
  <input type="hidden" name="option" value="mo2f_configure_miniorange_authenticator_validate" />
163
+ <input type="hidden" name="mo2f_configure_miniorange_authenticator_validate_nonce"
164
+ value="<?php echo wp_create_nonce( "mo2f-configure-miniorange-authenticator-validate-nonce" ) ?>"/>
165
  </form>
166
  </div>
167
  <form name="f" method="post" action="" id="mo2f_go_back_form" class="mo2f_display_none_forms">
168
  <input type="hidden" name="option" value="mo2f_go_back" />
169
+ <input type="hidden" name="mo2f_go_back_nonce"
170
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
171
  </form>
172
  <form name="f" method="post" id="mo2f_refresh_qr_form" action="" class="mo2f_display_none_forms">
173
  <input type="hidden" name="option" value="mo_auth_refresh_mobile_qrcode" />
174
+ <input type="hidden" name="mo_auth_refresh_mobile_qrcode_nonce"
175
+ value="<?php echo wp_create_nonce( "mo-auth-refresh-mobile-qrcode-nonce" ) ?>"/>
176
  </form>
177
  <input type="button" name="back" id="back_to_methods" class="button button-primary button-large" value="<?php echo mo2f_lt('Back');?>" />
178
 
views/configure_otp_over_sms CHANGED
@@ -11,6 +11,8 @@ function mo2f_configure_otp_over_sms( $user ) {
11
  <hr>
12
  <form name="f" method="post" action="" id="mo2f_verifyphone_form">
13
  <input type="hidden" name="option" value="mo2f_configure_otp_over_sms_send_otp"/>
 
 
14
 
15
  <div style="display:inline;">
16
  <input class="mo2f_table_textbox" style="width:200px;" type="text" name="verify_phone" id="phone"
@@ -22,6 +24,8 @@ function mo2f_configure_otp_over_sms( $user ) {
22
  </form>
23
  <form name="f" method="post" action="" id="mo2f_validateotp_form">
24
  <input type="hidden" name="option" value="mo2f_configure_otp_over_sms_validate"/>
 
 
25
  <p><?php echo mo2f_lt( 'Enter One Time Passcode' ); ?></p>
26
  <input class="mo2f_table_textbox" style="width:200px;" autofocus="true" type="text" name="otp_token"
27
  placeholder="<?php echo mo2f_lt( 'Enter OTP' ); ?>" style="width:95%;"/>
@@ -34,6 +38,8 @@ function mo2f_configure_otp_over_sms( $user ) {
34
  </form><br>
35
  <form name="f" method="post" action="" id="mo2f_go_back_form">
36
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
37
  </form>
38
  <script>
39
  jQuery("#phone").intlTelInput();
11
  <hr>
12
  <form name="f" method="post" action="" id="mo2f_verifyphone_form">
13
  <input type="hidden" name="option" value="mo2f_configure_otp_over_sms_send_otp"/>
14
+ <input type="hidden" name="mo2f_configure_otp_over_sms_send_otp_nonce"
15
+ value="<?php echo wp_create_nonce( "mo2f-configure-otp-over-sms-send-otp-nonce" ) ?>"/>
16
 
17
  <div style="display:inline;">
18
  <input class="mo2f_table_textbox" style="width:200px;" type="text" name="verify_phone" id="phone"
24
  </form>
25
  <form name="f" method="post" action="" id="mo2f_validateotp_form">
26
  <input type="hidden" name="option" value="mo2f_configure_otp_over_sms_validate"/>
27
+ <input type="hidden" name="mo2f_configure_otp_over_sms_validate_nonce"
28
+ value="<?php echo wp_create_nonce( "mo2f-configure-otp-over-sms-validate-nonce" ) ?>"/>
29
  <p><?php echo mo2f_lt( 'Enter One Time Passcode' ); ?></p>
30
  <input class="mo2f_table_textbox" style="width:200px;" autofocus="true" type="text" name="otp_token"
31
  placeholder="<?php echo mo2f_lt( 'Enter OTP' ); ?>" style="width:95%;"/>
38
  </form><br>
39
  <form name="f" method="post" action="" id="mo2f_go_back_form">
40
  <input type="hidden" name="option" value="mo2f_go_back"/>
41
+ <input type="hidden" name="mo2f_go_back_nonce"
42
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
43
  </form>
44
  <script>
45
  jQuery("#phone").intlTelInput();
views/customer_registration.php CHANGED
@@ -31,6 +31,8 @@
31
  </div>
32
 
33
  <form name="f" method="post" action="" id="mo2f_registration_closed_form">
 
 
34
  <input type="hidden" name="option" value="mo2f_registration_closed"/>
35
  </form>
36
 
31
  </div>
32
 
33
  <form name="f" method="post" action="" id="mo2f_registration_closed_form">
34
+ <input type="hidden" name="mo2f_registration_closed_nonce"
35
+ value="<?php echo wp_create_nonce( "mo2f-registration-closed-nonce" ) ?>"/>
36
  <input type="hidden" name="option" value="mo2f_registration_closed"/>
37
  </form>
38
 
views/feedback_form.php CHANGED
@@ -9,7 +9,7 @@
9
  wp_enqueue_style( 'wp-pointer' );
10
  wp_enqueue_script( 'wp-pointer' );
11
  wp_enqueue_script( 'utils' );
12
- wp_enqueue_style( 'mo_2_factor_admin_plugins_page_style', plugins_url( '/../includes/css/mo2f_plugins_page.css?version=5.1.8', __FILE__ ) );
13
 
14
  $action = 'install-plugin';
15
  $slug = 'miniorange-google-authenticator';
@@ -31,6 +31,8 @@
31
 
32
  <form name="f" method="post" action="" id="mo2f_feedback">
33
  <input type="hidden" name="mo2f_feedback" value="mo2f_feedback"/>
 
 
34
  <div>
35
  <p style="margin-left:2%">
36
  <span id="link_id"></span>
@@ -41,6 +43,7 @@
41
  "Upgrading to Premium",
42
  "Conflicts with other plugins",
43
  "Redirecting back to login page after Authentication",
 
44
  "Other Reasons:"
45
  );
46
 
@@ -81,6 +84,14 @@
81
  <form name="f" method="post" action="" id="mo2f_feedback_form_close">
82
 
83
  <input type="hidden" name="option" value="mo2f_skip_feedback"/>
 
 
 
 
 
 
 
 
84
  </form>
85
  </div>
86
 
@@ -91,6 +102,9 @@
91
  function handledeactivateplugin(){
92
  jQuery('#mo2f_feedback_form_close').submit();
93
  }
 
 
 
94
 
95
  jQuery('#other_plugins_installed').hide();
96
 
@@ -123,6 +137,11 @@
123
  jQuery('#link_id').html('<p style="background-color:#a3e8c2;padding:5px;">Thanks for upgrading. For setup instructions, please follow this guide' +
124
  ', <a href="<?php echo $setup_guide_link?>" download><b>DOWNLOAD GUIDE.</b></a></p>');
125
  jQuery('#link_id').show();
 
 
 
 
 
126
  }else if (reason == "Conflicts with other plugins") {
127
  jQuery('#query_feedback').attr("placeholder", "Can you please mention the plugin name, and the issue?");
128
  jQuery('#other_plugins_installed').show();
9
  wp_enqueue_style( 'wp-pointer' );
10
  wp_enqueue_script( 'wp-pointer' );
11
  wp_enqueue_script( 'utils' );
12
+ wp_enqueue_style( 'mo_2_factor_admin_plugins_page_style', plugins_url( '/../includes/css/mo2f_plugins_page.css?version=5.1.9', __FILE__ ) );
13
 
14
  $action = 'install-plugin';
15
  $slug = 'miniorange-google-authenticator';
31
 
32
  <form name="f" method="post" action="" id="mo2f_feedback">
33
  <input type="hidden" name="mo2f_feedback" value="mo2f_feedback"/>
34
+ <input type="hidden" name="mo2f_feedback_nonce"
35
+ value="<?php echo wp_create_nonce( "mo2f-feedback-nonce" ) ?>"/>
36
  <div>
37
  <p style="margin-left:2%">
38
  <span id="link_id"></span>
43
  "Upgrading to Premium",
44
  "Conflicts with other plugins",
45
  "Redirecting back to login page after Authentication",
46
+ "Database Error",
47
  "Other Reasons:"
48
  );
49
 
84
  <form name="f" method="post" action="" id="mo2f_feedback_form_close">
85
 
86
  <input type="hidden" name="option" value="mo2f_skip_feedback"/>
87
+ <input type="hidden" name="mo2f_skip_feedback_nonce"
88
+ value="<?php echo wp_create_nonce( "mo2f-skip-feedback-nonce" ) ?>"/>
89
+ </form>
90
+ <form name="f" method="post" action="" id="mo2f_fix_database_error_form">
91
+
92
+ <input type="hidden" name="option" value="mo2f_fix_database_error"/>
93
+ <input type="hidden" name="mo2f_fix_database_error_nonce"
94
+ value="<?php echo wp_create_nonce( "mo2f-fix-database-error-nonce" ) ?>"/>
95
  </form>
96
  </div>
97
 
102
  function handledeactivateplugin(){
103
  jQuery('#mo2f_feedback_form_close').submit();
104
  }
105
+ function mo2f_fix_database_error(){
106
+ jQuery('#mo2f_fix_database_error_form').submit();
107
+ }
108
 
109
  jQuery('#other_plugins_installed').hide();
110
 
137
  jQuery('#link_id').html('<p style="background-color:#a3e8c2;padding:5px;">Thanks for upgrading. For setup instructions, please follow this guide' +
138
  ', <a href="<?php echo $setup_guide_link?>" download><b>DOWNLOAD GUIDE.</b></a></p>');
139
  jQuery('#link_id').show();
140
+ }else if(reason=="Database Error"){
141
+ jQuery('#query_feedback').attr("placeholder", "Can you please mention the plugin name, and the issue?");
142
+ jQuery('#link_id').html('<p style="background-color:#a3e8c2;padding:5px;">Please click on this link to fix the issue' +
143
+ ', <a onclick="mo2f_fix_database_error();" style="cursor: pointer;"><b>Fix Database Error.</b></a></p>');
144
+ jQuery('#link_id').show();
145
  }else if (reason == "Conflicts with other plugins") {
146
  jQuery('#query_feedback').attr("placeholder", "Can you please mention the plugin name, and the issue?");
147
  jQuery('#other_plugins_installed').show();
views/test_email_verification CHANGED
@@ -19,12 +19,19 @@
19
 
20
  <form name="f" method="post" action="" id="mo2f_go_back_form">
21
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
22
  </form>
23
  <form name="f" method="post" id="mo2f_out_of_band_success_form" action="">
24
  <input type="hidden" name="option" value="mo2f_out_of_band_success"/>
 
 
25
  </form>
26
  <form name="f" method="post" id="mo2f_out_of_band_error_form" action="">
27
  <input type="hidden" name="option" value="mo2f_out_of_band_error"/>
 
 
 
28
  </form>
29
 
30
  <script>
19
 
20
  <form name="f" method="post" action="" id="mo2f_go_back_form">
21
  <input type="hidden" name="option" value="mo2f_go_back"/>
22
+ <input type="hidden" name="mo2f_go_back_nonce"
23
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
24
  </form>
25
  <form name="f" method="post" id="mo2f_out_of_band_success_form" action="">
26
  <input type="hidden" name="option" value="mo2f_out_of_band_success"/>
27
+ <input type="hidden" name="mo2f_out_of_band_success_nonce"
28
+ value="<?php echo wp_create_nonce( "mo2f-out-of-band-success-nonce" ) ?>"/>
29
  </form>
30
  <form name="f" method="post" id="mo2f_out_of_band_error_form" action="">
31
  <input type="hidden" name="option" value="mo2f_out_of_band_error"/>
32
+
33
+ <input type="hidden" name="mo2f_out_of_band_error_nonce"
34
+ value="<?php echo wp_create_nonce( "mo2f-out-of-band-error-nonce" ) ?>"/>
35
  </form>
36
 
37
  <script>
views/test_google_authy_authenticator CHANGED
@@ -8,6 +8,8 @@
8
 
9
  <form name="f" method="post" action="">
10
  <input type="hidden" name="option" value="mo2f_validate_google_authy_test"/>
 
 
11
 
12
  <input class="mo2f_table_textbox" style="width:200px;" autofocus="true" type="text" name="otp_token" required
13
  placeholder="<?php echo mo2f_lt( 'Enter OTP' ); ?>" style="width:95%;"/>
@@ -20,6 +22,8 @@
20
  </form>
21
  <form name="f" method="post" action="" id="mo2f_go_back_form">
22
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
23
  </form>
24
  <script>
25
  jQuery('#go_back').click(function () {
8
 
9
  <form name="f" method="post" action="">
10
  <input type="hidden" name="option" value="mo2f_validate_google_authy_test"/>
11
+ <input type="hidden" name="mo2f_validate_google_authy_test_nonce"
12
+ value="<?php echo wp_create_nonce( "mo2f-validate-google-authy-test-nonce" ) ?>"/>
13
 
14
  <input class="mo2f_table_textbox" style="width:200px;" autofocus="true" type="text" name="otp_token" required
15
  placeholder="<?php echo mo2f_lt( 'Enter OTP' ); ?>" style="width:95%;"/>
22
  </form>
23
  <form name="f" method="post" action="" id="mo2f_go_back_form">
24
  <input type="hidden" name="option" value="mo2f_go_back"/>
25
+ <input type="hidden" name="mo2f_go_back_nonce"
26
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
27
  </form>
28
  <script>
29
  jQuery('#go_back').click(function () {
views/test_kba_security_questions CHANGED
@@ -7,7 +7,9 @@
7
 
8
  <form name="f" method="post" action="" id="mo2f_test_kba_form">
9
  <input type="hidden" name="option" value="mo2f_validate_kba_details"/>
10
-
 
 
11
  <div id="mo2f_kba_content">
12
  <?php if ( isset( $_SESSION['mo_2_factor_kba_questions'] ) ) {
13
  echo $_SESSION['mo_2_factor_kba_questions'][0];
@@ -40,6 +42,8 @@
40
  </form>
41
  <form name="f" method="post" action="" id="mo2f_go_back_form">
42
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
43
  </form>
44
  <script>
45
  jQuery('#go_back').click(function () {
7
 
8
  <form name="f" method="post" action="" id="mo2f_test_kba_form">
9
  <input type="hidden" name="option" value="mo2f_validate_kba_details"/>
10
+ <input type="hidden" name="mo2f_validate_kba_details_nonce"
11
+ value="<?php echo wp_create_nonce( "mo2f-validate-kba-details-nonce" ) ?>"/>
12
+
13
  <div id="mo2f_kba_content">
14
  <?php if ( isset( $_SESSION['mo_2_factor_kba_questions'] ) ) {
15
  echo $_SESSION['mo_2_factor_kba_questions'][0];
42
  </form>
43
  <form name="f" method="post" action="" id="mo2f_go_back_form">
44
  <input type="hidden" name="option" value="mo2f_go_back"/>
45
+ <input type="hidden" name="mo2f_go_back_nonce"
46
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
47
  </form>
48
  <script>
49
  jQuery('#go_back').click(function () {
views/test_miniorange_push_notification CHANGED
@@ -17,12 +17,18 @@
17
 
18
  <form name="f" method="post" action="" id="mo2f_go_back_form">
19
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
20
  </form>
21
  <form name="f" method="post" id="mo2f_push_success_form" action="">
22
  <input type="hidden" name="option" value="mo2f_out_of_band_success"/>
 
 
23
  </form>
24
  <form name="f" method="post" id="mo2f_push_error_form" action="">
25
  <input type="hidden" name="option" value="mo2f_out_of_band_error"/>
 
 
26
  </form>
27
 
28
  <script>
17
 
18
  <form name="f" method="post" action="" id="mo2f_go_back_form">
19
  <input type="hidden" name="option" value="mo2f_go_back"/>
20
+ <input type="hidden" name="mo2f_go_back_nonce"
21
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
22
  </form>
23
  <form name="f" method="post" id="mo2f_push_success_form" action="">
24
  <input type="hidden" name="option" value="mo2f_out_of_band_success"/>
25
+ <input type="hidden" name="mo2f_out_of_band_success_nonce"
26
+ value="<?php echo wp_create_nonce( "mo2f-out-of-band-success-nonce" ) ?>"/>
27
  </form>
28
  <form name="f" method="post" id="mo2f_push_error_form" action="">
29
  <input type="hidden" name="option" value="mo2f_out_of_band_error"/>
30
+ <input type="hidden" name="mo2f_out_of_band_error_nonce"
31
+ value="<?php echo wp_create_nonce( "mo2f-out-of-band-error-nonce" ) ?>"/>
32
  </form>
33
 
34
  <script>
views/test_miniorange_qr_code_authentication CHANGED
@@ -34,12 +34,18 @@ function mo2f_test_miniorange_qr_code_authentication( $user ) {
34
  <div id="mobile_registered">
35
  <form name="f" method="post" id="mo2f_mobile_authenticate_success_form" action="">
36
  <input type="hidden" name="option" value="mo2f_mobile_authenticate_success"/>
 
 
37
  </form>
38
  <form name="f" method="post" id="mo2f_mobile_authenticate_error_form" action="">
39
  <input type="hidden" name="option" value="mo2f_mobile_authenticate_error"/>
 
 
40
  </form>
41
  <form name="f" method="post" action="" id="mo2f_go_back_form">
42
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
43
  <input type="submit" name="validate" id="validate" class="button button-primary button-large"
44
  value="<?php echo mo2f_lt( 'Back' ); ?>"/>
45
  </form>
34
  <div id="mobile_registered">
35
  <form name="f" method="post" id="mo2f_mobile_authenticate_success_form" action="">
36
  <input type="hidden" name="option" value="mo2f_mobile_authenticate_success"/>
37
+ <input type="hidden" name="mo2f_mobile_authenticate_success_nonce"
38
+ value="<?php echo wp_create_nonce( "mo2f-mobile-authenticate-success-nonce" ) ?>"/>
39
  </form>
40
  <form name="f" method="post" id="mo2f_mobile_authenticate_error_form" action="">
41
  <input type="hidden" name="option" value="mo2f_mobile_authenticate_error"/>
42
+ <input type="hidden" name="mo2f_mobile_authenticate_error_nonce"
43
+ value="<?php echo wp_create_nonce( "mo2f-mobile-authenticate-error-nonce" ) ?>"/>
44
  </form>
45
  <form name="f" method="post" action="" id="mo2f_go_back_form">
46
  <input type="hidden" name="option" value="mo2f_go_back"/>
47
+ <input type="hidden" name="mo2f_go_back_nonce"
48
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
49
  <input type="submit" name="validate" id="validate" class="button button-primary button-large"
50
  value="<?php echo mo2f_lt( 'Back' ); ?>"/>
51
  </form>
views/test_miniorange_soft_token CHANGED
@@ -9,7 +9,8 @@
9
  </p>
10
  <form name="f" method="post" action="" id="mo2f_test_token_form">
11
  <input type="hidden" name="option" value="mo2f_validate_soft_token"/>
12
-
 
13
  <input class="mo2f_table_textbox" style="width:200px;" autofocus="true" type="text" name="otp_token" required
14
  placeholder="<?php echo mo2f_lt( 'Enter OTP' ); ?>" style="width:95%;"/>
15
 
@@ -23,6 +24,8 @@
23
 
24
  <form name="f" method="post" action="" id="mo2f_go_back_form">
25
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
26
  </form>
27
  <script>
28
  jQuery('#go_back').click(function () {
9
  </p>
10
  <form name="f" method="post" action="" id="mo2f_test_token_form">
11
  <input type="hidden" name="option" value="mo2f_validate_soft_token"/>
12
+ <input type="hidden" name="mo2f_validate_soft_token_nonce"
13
+ value="<?php echo wp_create_nonce( "mo2f-validate-soft-token-nonce" ) ?>"/>
14
  <input class="mo2f_table_textbox" style="width:200px;" autofocus="true" type="text" name="otp_token" required
15
  placeholder="<?php echo mo2f_lt( 'Enter OTP' ); ?>" style="width:95%;"/>
16
 
24
 
25
  <form name="f" method="post" action="" id="mo2f_go_back_form">
26
  <input type="hidden" name="option" value="mo2f_go_back"/>
27
+ <input type="hidden" name="mo2f_go_back_nonce"
28
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
29
  </form>
30
  <script>
31
  jQuery('#go_back').click(function () {
views/test_otp_over_sms CHANGED
@@ -10,7 +10,9 @@ function mo2f_test_otp_over_sms( $user ) {
10
 
11
  <form name="f" method="post" action="" id="mo2f_test_token_form">
12
  <input type="hidden" name="option" value="mo2f_validate_otp_over_sms"/>
13
-
 
 
14
  <input class="mo2f_table_textbox" style="width:200px;" autofocus="true" type="text" name="otp_token" required
15
  placeholder="<?php echo mo2f_lt( 'Enter OTP' ); ?>" style="width:95%;"/>
16
  <a href="#resendsmslink"><?php echo mo2f_lt( 'Resend OTP ?' ); ?></a>
@@ -23,14 +25,18 @@ function mo2f_test_otp_over_sms( $user ) {
23
  </form>
24
  <form name="f" method="post" action="" id="mo2f_go_back_form">
25
  <input type="hidden" name="option" value="mo2f_go_back"/>
 
 
26
  </form>
27
 
28
  <form name="f" method="post" action="" id="mo2f_2factor_test_authentication_method_form">
29
  <input type="hidden" name="option" value="mo_2factor_test_authentication_method"/>
 
 
30
  <input type="hidden" name="mo2f_configured_2FA_method_test" id="mo2f_configured_2FA_method_test"
31
  value="OTP Over SMS"/>
32
  </form>
33
- <form name="f" method="post" action="" id="mo2f_test_smsotp_form">
34
 
35
 
36
  <script>
10
 
11
  <form name="f" method="post" action="" id="mo2f_test_token_form">
12
  <input type="hidden" name="option" value="mo2f_validate_otp_over_sms"/>
13
+ <input type="hidden" name="mo2f_validate_otp_over_sms_nonce"
14
+ value="<?php echo wp_create_nonce( "mo2f-validate-otp-over-sms-nonce" ) ?>"/>
15
+
16
  <input class="mo2f_table_textbox" style="width:200px;" autofocus="true" type="text" name="otp_token" required
17
  placeholder="<?php echo mo2f_lt( 'Enter OTP' ); ?>" style="width:95%;"/>
18
  <a href="#resendsmslink"><?php echo mo2f_lt( 'Resend OTP ?' ); ?></a>
25
  </form>
26
  <form name="f" method="post" action="" id="mo2f_go_back_form">
27
  <input type="hidden" name="option" value="mo2f_go_back"/>
28
+ <input type="hidden" name="mo2f_go_back_nonce"
29
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
30
  </form>
31
 
32
  <form name="f" method="post" action="" id="mo2f_2factor_test_authentication_method_form">
33
  <input type="hidden" name="option" value="mo_2factor_test_authentication_method"/>
34
+ <input type="hidden" name="mo_2factor_test_authentication_method_nonce"
35
+ value="<?php echo wp_create_nonce( "mo-2factor-test-authentication-method-nonce" ) ?>"/>
36
  <input type="hidden" name="mo2f_configured_2FA_method_test" id="mo2f_configured_2FA_method_test"
37
  value="OTP Over SMS"/>
38
  </form>
39
+
40
 
41
 
42
  <script>