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

Version Description

  • Google Authenticator-Two Factor Authentication (2FA) : On-premise two factor released with multiple users support for some authentication methods.
Download this release

Release Info

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

Code changes from version 5.3.23 to 5.3.24

Files changed (150) hide show
  1. api/Denied.php +0 -28
  2. api/Expire.php +0 -29
  3. api/Mo2f_OnPremRedirect.php +176 -0
  4. api/Validate.php +0 -29
  5. api/class-customer-setup.php +194 -115
  6. api/class-rba-attributes.php +35 -19
  7. api/class-two-factor-setup.php +1 -1
  8. controllers/account.php +5 -8
  9. controllers/advanced-blocking.php +43 -25
  10. controllers/backup.php +0 -79
  11. controllers/backup/backup.php +2 -0
  12. controllers/backup/backup_ajax.php +157 -0
  13. controllers/backup/backup_controller.php +2 -0
  14. controllers/backup/backup_created_report.php +2 -0
  15. controllers/backup/backup_created_result.php +14 -0
  16. controllers/backup/backup_schdule.php +22 -0
  17. controllers/backup_ajax.php +0 -74
  18. controllers/change-password.php +4 -4
  19. controllers/content-protection.php +16 -7
  20. controllers/dashboard.php +1 -1
  21. controllers/dashboard_ajax.php +11 -10
  22. controllers/feedback_form.php +1 -14
  23. controllers/ip-blocking.php +9 -17
  24. controllers/licensing.php +2 -2
  25. controllers/login-security.php +10 -10
  26. controllers/login-spam.php +2 -3
  27. controllers/main_controller.php +57 -38
  28. controllers/malware_scanner/malware_scan_ajax.php +2 -8
  29. controllers/malware_scanner/scan_malware.php +2 -2
  30. controllers/malware_scanner/scan_malware_report.php +1 -1
  31. controllers/malware_scanner/scan_malware_settings.php +2 -2
  32. controllers/malware_scanner/scan_malware_summary.php +1 -1
  33. controllers/navbar.php +4 -6
  34. controllers/newtork_security_features.php +2 -2
  35. controllers/notification-settings.php +2 -2
  36. controllers/registration-security.php +3 -3
  37. controllers/reports.php +2 -2
  38. controllers/request_demo.php +51 -0
  39. controllers/support.php +2 -2
  40. controllers/tour-model.php +2 -13
  41. controllers/troubleshooting.php +2 -2
  42. controllers/twofa/mo2fa_common_login.php +57 -14
  43. controllers/twofa/setup_twofa.php +24 -1
  44. controllers/twofa/two_fa.php +1 -1
  45. controllers/twofa/two_fa_addon.php +2 -1
  46. controllers/twofa/two_fa_custom_form.php +1 -1
  47. controllers/twofa/two_fa_custom_login.php +1 -1
  48. controllers/twofa/two_fa_login_option.php +1 -1
  49. controllers/twofa/two_fa_rba.php +1 -1
  50. controllers/twofa/two_fa_shortcode.php +1 -1
  51. controllers/twofa/two_fa_unlimittedUser.php +4 -0
  52. controllers/twofa/two_fa_unlimittedUser_ajax.php +47 -0
  53. controllers/twofa/two_fa_video_guide.php +1 -1
  54. controllers/twofa/two_factor_ajax.php +185 -0
  55. controllers/upgrade.php +1 -1
  56. controllers/waf.php +13 -9
  57. controllers/wpns-loginsecurity-ajax.php +5 -48
  58. database/database_functions.php +80 -31
  59. database/database_functions_2fa.php +20 -1
  60. handler/WAF/database/mo-waf-db.php +5 -2
  61. handler/WAF/mo-waf-plugin.php +22 -14
  62. handler/WAF/mo-waf.php +8 -3
  63. handler/WAF/waf-include.php +2 -1
  64. handler/ajax.php +6 -103
  65. handler/backup.php +292 -162
  66. handler/feedback_form.php +46 -1
  67. handler/login.php +105 -69
  68. handler/malware_scanner.php +669 -0
  69. handler/malware_scanner/malware_scanner_cron.php +2 -4
  70. handler/malware_scanner/scanner_set_cron.php +3 -4
  71. handler/mo-block.html +9 -0
  72. handler/mo-block.php +0 -32
  73. handler/mo-error.html +11 -0
  74. handler/mo-error.php +0 -34
  75. handler/mo-waf-plugin.php +18 -12
  76. handler/mo-waf.php +20 -13
  77. handler/recaptcha.php +2 -3
  78. handler/registration.php +14 -3
  79. handler/security_features +0 -6
  80. handler/signature/APLFI.php +1 -1
  81. handler/{encryption.php → twofa/encryption.php} +1 -2
  82. handler/{gaonprem.php → twofa/gaonprem.php} +5 -5
  83. handler/twofa/setup_twofa.php +169 -46
  84. handler/twofa/two_fa_constants.php +13 -1
  85. handler/twofa/two_fa_login.php +92 -28
  86. handler/twofa/two_fa_pass2login.php +352 -120
  87. handler/twofa/two_fa_settings.php +333 -147
  88. handler/twofa/two_fa_utility.php +6 -3
  89. helper/constants.php +7 -4
  90. helper/curl.php +39 -6
  91. helper/dashboard_security_notification.php +66 -8
  92. helper/messages.php +9 -1
  93. helper/pluginUtility.php +3 -1
  94. helper/plugins.php +1 -1
  95. helper/utility.php +17 -4
  96. includes/css/bootstrap.min.css +1875 -0
  97. includes/css/hide-login.css +317 -0
  98. includes/css/style_settings.css +118 -1489
  99. includes/images/{normal1.PNG → normal.png} +0 -0
  100. includes/images/normal1.png +0 -0
  101. includes/jquery-qrcode/README.md +7 -5
  102. includes/jquery-qrcode/jquery-qrcode.js +2406 -1923
  103. includes/jquery-qrcode/jquery-qrcode.min.js +2 -2
  104. includes/js/settings_page.js +4 -0
  105. miniorange_2_factor_settings.php +249 -64
  106. readme.txt +7 -1
  107. uninstall.php +40 -26
  108. views/account/register.php +1 -1
  109. views/advanced-blocking.php +417 -8
  110. views/backup.php +0 -232
  111. views/backup/backup.php +79 -0
  112. views/backup/backup_created_report.php +87 -0
  113. views/backup/backup_schdule.php +206 -0
  114. views/backup/backup_setting_view.php +162 -0
  115. views/content-protection.php +8 -0
  116. views/dashboard.php +2 -2
  117. views/error/403.php +0 -12
  118. views/login-security.php +31 -35
  119. views/login_spam.php +3 -3
  120. views/malware_scanner/malware_scan.php +4 -4
  121. views/malware_scanner/scan_report_view.php +1 -1
  122. views/malware_scanner/scan_summary_view.php +2 -10
  123. views/navbar.php +26 -9
  124. views/rate-limiting.php +14 -12
  125. views/request_demo.php +43 -0
  126. views/test/test_twofa_email_verification.php +76 -0
  127. views/test/test_twofa_google_authy_authenticator.php +35 -0
  128. views/test/test_twofa_kba_questions.php +55 -0
  129. views/test/test_twofa_miniorange_push_notification.php +68 -0
  130. views/test/test_twofa_miniorange_qrcode_authentication.php +97 -0
  131. views/test/test_twofa_miniorange_soft_token.php +38 -0
  132. views/test/test_twofa_otp_over_sms.php +51 -0
  133. views/twofa/setup/setup_kba_questions.php +1 -1
  134. views/twofa/setup/setup_miniorange_authenticator.php +1 -1
  135. views/twofa/setup_twofa.php +138 -57
  136. views/twofa/test/test_twofa_email_verification.php +83 -37
  137. views/twofa/test/test_twofa_kba_questions.php +65 -4
  138. views/twofa/test/test_twofa_miniorange_push_notification.php +1 -1
  139. views/twofa/test/test_twofa_miniorange_qrcode_authentication.php +1 -1
  140. views/twofa/two_fa.php +53 -40
  141. views/twofa/two_fa_custom_form.php +91 -24
  142. views/twofa/two_fa_custom_login.php +1 -0
  143. views/twofa/two_fa_login_option.php +37 -16
  144. views/twofa/two_fa_rba.php +2 -3
  145. views/twofa/two_fa_setup_notification.php +7 -0
  146. views/twofa/two_fa_shortcode.php +3 -4
  147. views/twofa/two_fa_unlimittedUser.php +697 -0
  148. views/upgrade.php +3 -3
  149. views/waf-settings.php +2 -2
  150. views/waf.php +127 -221
api/Denied.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
-
3
- echo "<div style='background-color: #d5e3d9; height:850px;' >
4
- <div style='height:350px; background-color: #3CB371; border-radius: 2px; padding:2%; '>
5
- <div class='mo2f_tamplate_layout' style='background-color: #ffffff;border-radius: 5px;box-shadow: 0 5px 15px rgba(0,0,0,.5); width:800px;height:350px; align-self: center; margin: 180px auto; ' >
6
- <img alt='logo' style='margin-left:240px ;
7
- margin-top:10px;width=40%;' src='https://auth.miniorange.com/moas/images/logo_large.png' />
8
- <div><hr></div>
9
-
10
- <tbody>
11
- <tr>
12
- <td>
13
-
14
- <p style='margin-top:0;margin-bottom:10px'>
15
- <p style='margin-top:0;margin-bottom:10px'> <h1 style='color:red;text-align:center;font-size:55px'>TRANSACTION DENIED </h1></p>
16
- <p style='margin-top:0;margin-bottom:10px'>
17
- <p style='margin-top:0;margin-bottom:10px;text-align:center'><h2 style='text-align:center'>Transaction has been Canceled.<br><br>Please Try Again.</h2></p>
18
- <p style='margin-top:0;margin-bottom:0px;font-size:11px'>
19
-
20
- </td>
21
- </tr>
22
- </tbody>
23
-
24
-
25
- </div>
26
- </div> ";
27
-
28
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
api/Expire.php DELETED
@@ -1,29 +0,0 @@
1
- <?php
2
-
3
- echo "<div style='background-color: #d5e3d9; height:850px;' >
4
- <div style='height:350px; background-color: #3CB371; border-radius: 2px; padding:2%; '>
5
- <div class='mo2f_tamplate_layout' style='background-color: #ffffff;border-radius: 5px;box-shadow: 0 5px 15px rgba(0,0,0,.5); width:800px;height:350px; align-self: center; margin: 180px auto; ' >
6
- <img alt='logo' style='margin-left:240px ;
7
- margin-top:10px;width=40%;' src='https://auth.miniorange.com/moas/images/logo_large.png' />
8
- <div><hr></div>
9
-
10
-
11
- <tbody>
12
- <tr>
13
- <td>
14
-
15
- <p style='margin-top:0;margin-bottom:10px'>
16
- <p style='margin-top:0;margin-bottom:10px'> <h1 style='color:red;text-align:center;font-size:55px'>You are not authorized to perform this action</h1></p>
17
- <p style='margin-top:0;margin-bottom:10px;text-align:center'><h2 style='text-align:center'>Please contact to your admin</h2></p>
18
- <p style='margin-top:0;margin-bottom:0px;font-size:11px'>
19
-
20
- </td>
21
- </tr>
22
- </tbody>
23
- </table>
24
-
25
-
26
- </div>
27
- </div> ";
28
-
29
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
api/Mo2f_OnPremRedirect.php ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <?php
3
+
4
+
5
+ class Mo2f_OnPremRedirect {
6
+
7
+ function OnpremValidateRedirect($authType, $otpToken){
8
+
9
+ switch($authType){
10
+
11
+ case "GOOGLE AUTHENTICATOR" :$content = $this->mo2f_google_authenticator_onpremise($otpToken);
12
+ return $content;
13
+ break;
14
+ case "KBA": $content = $this->mo2f_kba_onpremise();
15
+ return $content;
16
+ break;
17
+ case "OUT OF BAND EMAIL":
18
+ break;
19
+ case "EMAIL":
20
+ break;
21
+ }
22
+
23
+ }
24
+
25
+ function mo2f_kba_onpremise(){
26
+ $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
27
+ if(isset($_POST['validate'])){
28
+ $user_id = wp_get_current_user()->ID;
29
+ }
30
+ else{
31
+ $user_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_current_user_id',$session_id_encrypt );
32
+ }
33
+ $redirect_to = isset( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : null;
34
+ $kba_ans_1 = sanitize_text_field( $_POST['mo2f_answer_1'] );
35
+ $kba_ans_2 = sanitize_text_field( $_POST['mo2f_answer_2'] );
36
+ $questions_challenged = get_user_meta($user_id ,'kba_questions_user');
37
+ $questions_challenged = $questions_challenged[0];
38
+ $all_ques_ans = (get_user_meta($user_id , 'mo2f_kba_challenge'));
39
+ $all_ques_ans = $all_ques_ans[0];
40
+ $ans_1 = $all_ques_ans[$questions_challenged[0]];
41
+ $ans_2 = $all_ques_ans[$questions_challenged[1]];
42
+ $check_trust_device = isset( $_POST['mo2f_trust_device'] ) ? $_POST['mo2f_trust_device'] : 'false';
43
+ $mo2f_rba_status = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_rba_status',$session_id_encrypt );
44
+
45
+ $pass2fa = new Miniorange_Password_2Factor_Login;
46
+ $twofa_Settings = new Miniorange_Authentication;
47
+ if(!strcmp(md5($kba_ans_1),$ans_1 ) && !strcmp(md5($kba_ans_2), $ans_2) ){
48
+ $arr = array('status' => 'SUCCESS','message'=>'Successfully validated.');
49
+ $content = json_encode($arr);
50
+ delete_user_meta( $user_id, 'test_2FA' );
51
+ return $content;
52
+ }
53
+ else {
54
+ $arr = array('status' => 'FAILED','message'=>'TEST FAILED.');
55
+ $content = json_encode($arr);
56
+ return $content;
57
+ }
58
+
59
+ }
60
+
61
+ function OnpremSendRedirect($useremail,$authType){
62
+
63
+ switch($authType){
64
+
65
+ case "Email Verification":$content = $this->mo2f_pass2login_push_email_onpremise($useremail);
66
+ break;
67
+ case "EMAIL":
68
+ break;
69
+ }
70
+
71
+ }
72
+
73
+ function mo2f_google_authenticator_onpremise($otpToken){
74
+ include_once dirname(dirname( __FILE__ )) . DIRECTORY_SEPARATOR. 'handler'.DIRECTORY_SEPARATOR. 'twofa' . DIRECTORY_SEPARATOR . 'gaonprem.php';
75
+ $gauth_obj= new Google_auth_onpremise();
76
+ $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
77
+ if(is_user_logged_in()){
78
+ $user = wp_get_current_user();
79
+ $user_id = $user->ID;
80
+ }else{
81
+ $user_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_current_user_id',$session_id_encrypt );
82
+ }
83
+ $secret= $gauth_obj->mo_GAuth_get_secret($user_id);
84
+ $content=$gauth_obj->verifyCode($secret, $otpToken);
85
+ return $content;
86
+ }
87
+
88
+ function mo2f_pass2login_push_email_onpremise($current_user, $redirect_to=null, $session_id=null)
89
+ {
90
+
91
+ global $Mo2fdbQueries;
92
+ if(is_null($session_id)){
93
+ $session_id=$this->create_session();
94
+ }
95
+ $email = get_user_meta($current_user->ID,'email',true);
96
+ $subject = "2-Factor Authentication(Email verification)";
97
+ $headers = array('Content-Type: text/html; charset=UTF-8');
98
+ $txid = '';
99
+ $otpToken = '';
100
+ $otpTokenD = '';
101
+ for($i=1;$i<7;$i++)
102
+ {
103
+ $otpToken .= rand(0,9);
104
+ $txid .= rand(100,999);
105
+ $otpTokenD .= rand(0,9);
106
+ }
107
+ $otpTokenH = hash('sha512',$otpToken);
108
+ $otpTokenDH = hash('sha512', $otpTokenD);
109
+ update_user_meta($current_user->ID,'mo2f_EV_txid',$txid);
110
+ $userID = hash('sha512',$current_user->ID);
111
+ update_site_option($userID,$otpTokenH);
112
+ update_site_option($txid,3);
113
+ $userIDd = $userID . 'D';
114
+ update_site_option($userIDd,$otpTokenDH);
115
+
116
+ $message = $this->getEmailTemplate($userID, $otpTokenH,$otpTokenDH,$txid,$email);
117
+ $result = wp_mail($email,$subject,$message,$headers);
118
+
119
+ $response=array("txId"=>$txid);
120
+ $hidden_user_email = MO2f_Utility::mo2f_get_hidden_email( $email );
121
+ if($result)
122
+ {
123
+ $response['status']='SUCCESS';
124
+ $time = "time".$txid;
125
+ $currentTimeInMillis = round(microtime(true) * 1000);
126
+ update_site_option($time,$currentTimeInMillis);
127
+ // $mo2fa_login_message = __('An email has been sent to ','miniorange-2-factor-authentication').$hidden_user_email. '. ' .__('We are waiting for your approval.','miniorange-2-factor-authentication');
128
+ // $mo2fa_login_status = 'MO_2_FACTOR_CHALLENGE_OOB_EMAIL';
129
+ // $this->miniorange_pass2login_form_fields($mo2fa_login_status, $mo2fa_login_message, $redirect_to,null,$session_id);
130
+ }
131
+ else
132
+ {
133
+ $response['status']='FAILED';
134
+ //$response=array("status"=>'FAILED');
135
+ $key = get_option( 'mo2f_encryption_key' );
136
+ $session_id_encrypt = MO2f_Utility::encrypt_data($session_id, $key);
137
+ //$this->mo2fa_pass2login($redirect_to,$session_id_encrypt);
138
+ }
139
+
140
+ return json_encode($response);
141
+ }
142
+
143
+ function getEmailTemplate($userID, $otpTokenH,$otpTokenDH,$txid,$email){
144
+ $url = get_site_option('siteurl').'/wp-login.php?';
145
+ $message = '<table cellpadding="25" style="margin:0px auto">
146
+ <tbody>
147
+ <tr>
148
+ <td>
149
+ <table cellpadding="24" width="584px" style="margin:0 auto;max-width:584px;background-color:#f6f4f4;border:1px solid #a8adad">
150
+ <tbody>
151
+ <tr>
152
+ <td><img src="https://ci5.googleusercontent.com/proxy/10EQeM1udyBOkfD2dwxGhIaMXV4lOwCRtUecpsDkZISL0JIkOL2JhaYhVp54q6Sk656rW2rpAFJFEgGQiAOVcYIIKxXYMHHMNSNB=s0-d-e1-ft#https://login.xecurify.com/moas/images/xecurify-logo.png" style="color:#5fb336;text-decoration:none;display:block;width:auto;height:auto;max-height:35px" class="CToWUd"></td>
153
+ </tr>
154
+ </tbody>
155
+ </table>
156
+ <table cellpadding="24" style="background:#fff;border:1px solid #a8adad;width:584px;border-top:none;color:#4d4b48;font-family:Arial,Helvetica,sans-serif;font-size:13px;line-height:18px">
157
+ <tbody>
158
+ <tr>
159
+ <td>
160
+ <p style="margin-top:0;margin-bottom:20px">Dear Customers,</p>
161
+ <p style="margin-top:0;margin-bottom:10px">You initiated a transaction <b>WordPress 2 Factor Authentication Plugin</b>:</p>
162
+ <p style="margin-top:0;margin-bottom:10px">To accept, <a href="'.$url.'userID='.$userID.'&amp;accessToken='.$otpTokenH.'&amp;secondFactorAuthType=OUT+OF+BAND+EMAIL&amp;Txid='.$txid.'&amp;user='.$email.'" target="_blank" data-saferedirecturl="https://www.google.com/url?q=https://login.xecurify.com/moas/rest/validate-otp?customerKey%3D182589%26otpToken%3D735705%26secondFactorAuthType%3DOUT%2BOF%2BBAND%2BEMAIL%26user%3D'.$email.'&amp;source=gmail&amp;ust=1569905139580000&amp;usg=AFQjCNExKCcqZucdgRm9-0m360FdYAIioA">Accept Transaction</a></p>
163
+ <p style="margin-top:0;margin-bottom:10px">To deny, <a href="'.$url.'userID='.$userID.'&amp;accessToken='.$otpTokenDH.'&amp;secondFactorAuthType=OUT+OF+BAND+EMAIL&amp;Txid='.$txid.'&amp;user='.$email.'" target="_blank" data-saferedirecturl="https://www.google.com/url?q=https://login.xecurify.com/moas/rest/validate-otp?customerKey%3D182589%26otpToken%3D735705%26secondFactorAuthType%3DOUT%2BOF%2BBAND%2BEMAIL%26user%3D'.$email.'&amp;source=gmail&amp;ust=1569905139580000&amp;usg=AFQjCNExKCcqZucdgRm9-0m360FdYAIioA">Deny Transaction</a></p><div><div class="adm"><div id="q_31" class="ajR h4" data-tooltip="Hide expanded content" aria-label="Hide expanded content" aria-expanded="true"><div class="ajT"></div></div></div><div class="im">
164
+ <p style="margin-top:0;margin-bottom:15px">Thank you,<br>miniOrange Team</p>
165
+ <p style="margin-top:0;margin-bottom:0px;font-size:11px">Disclaimer: This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed.</p>
166
+ </div></div></td>
167
+ </tr>
168
+ </tbody>
169
+ </table>
170
+ </td>
171
+ </tr>
172
+ </tbody>
173
+ </table>';
174
+ return $message;
175
+ }
176
+ }
api/Validate.php DELETED
@@ -1,29 +0,0 @@
1
-
2
- <?php
3
-
4
- echo "<div style='background-color: #d5e3d9; height:850px;' >
5
- <div style='height:350px; background-color: #3CB371; border-radius: 2px; padding:2%; '>
6
- <div class='mo2f_tamplate_layout' style='background-color: #ffffff;border-radius: 5px;box-shadow: 0 5px 15px rgba(0,0,0,.5); width:850px;height:350px; align-self: center; margin: 180px auto; ' >
7
- <img alt='logo' style='margin-left:240px ;
8
- margin-top:10px;width=40%;' src='https://auth.miniorange.com/moas/images/logo_large.png' />
9
- <div><hr></div>
10
-
11
- <tbody>
12
- <tr>
13
- <td>
14
-
15
- <p style='margin-top:0;margin-bottom:10px'>
16
- <p style='margin-top:0;margin-bottom:10px'> <h1 style='color:green;text-align:center;font-size:50px'>TRANSACTION SUCCESSFUL </h1></p>
17
- <p style='margin-top:0;margin-bottom:10px'>
18
- <p style='margin-top:0;margin-bottom:10px;text-align:center'><h2 style='text-align:center'>Transaction has been successfully validated.<br><br>Please continue with the transaction.</h2></p>
19
- <p style='margin-top:0;margin-bottom:0px;font-size:11px'>
20
-
21
- </td>
22
- </tr>
23
- </tbody>
24
-
25
-
26
- </div>
27
- </div> ";
28
-
29
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
api/class-customer-setup.php CHANGED
@@ -23,7 +23,7 @@
23
  * Contains Request Calls to Customer service.
24
  **/
25
 
26
- include_once dirname( __FILE__ ) . '/mo2f_api.php';
27
 
28
  class Customer_Setup {
29
 
@@ -34,6 +34,7 @@ class Customer_Setup {
34
 
35
  private $auth_mode = 2; // miniorange test or not
36
  private $https_mode = false; // website http or https
 
37
 
38
  function check_customer() {
39
  $url = MO_HOST_NAME . "/moas/rest/customer/check-if-exists";
@@ -77,10 +78,12 @@ class Customer_Setup {
77
  );
78
 
79
 
 
80
  $headers = array("Content-Type"=>"application/json","charset"=>"UTF-8","Authorization"=>"Basic");
81
 
82
  $field_string = json_encode ( $fields );
83
- $response = $mo2fApi->make_curl_call( $url, $field_string,$headers );
 
84
  return $response;
85
 
86
  }
@@ -201,65 +204,73 @@ class Customer_Setup {
201
 
202
 
203
  function send_otp_token( $uKey, $authType, $cKey, $apiKey ) {
204
- if ( ! MO2f_Utility::is_curl_installed() ) {
205
- $message = 'Please enable curl extension. <a href="admin.php?page=mo_2fa_troubleshooting">Click here</a> for the steps to enable curl.';
206
-
207
- return json_encode( array( "status" => 'ERROR', "message" => $message ) );
208
- }
209
-
210
- $url = MO_HOST_NAME . '/moas/api/auth/challenge';
211
- $mo2fApi= new Mo2f_Api();
212
- /* The customer Key provided to you */
213
- $customerKey = $cKey;
214
-
215
- /* The customer API Key provided to you */
216
- $apiKey = $apiKey;
217
-
218
- /* Current time in milliseconds since midnight, January 1, 1970 UTC. */
219
- $currentTimeInMillis = $mo2fApi->get_timestamp();
220
-
221
- /* Creating the Hash using SHA-512 algorithm */
222
- $stringToHash = $customerKey . $currentTimeInMillis . $apiKey;
223
- $hashValue = hash( "sha512", $stringToHash );
224
-
225
- $headers = $mo2fApi->get_http_header_array();
226
-
227
- $fields = '';
228
- if ( $authType == 'EMAIL' || $authType == 'OUT OF BAND EMAIL' ) {
229
- $fields = array(
230
- 'customerKey' => $customerKey,
231
- 'email' => $uKey,
232
- 'authType' => $authType,
233
- 'transactionName' => 'WordPress 2 Factor Authentication Plugin'
234
- );
235
- } else if ( $authType == 'SMS' ) {
236
- $authType = "SMS";
237
- $fields = array(
238
- 'customerKey' => $customerKey,
239
- 'phone' => $uKey,
240
- 'authType' => $authType
241
- );
242
- } else {
243
- $fields = array(
244
- 'customerKey' => $customerKey,
245
- 'username' => $uKey,
246
- 'authType' => $authType,
247
- 'transactionName' => 'WordPress 2 Factor Authentication Plugin'
248
- );
249
- }
250
-
251
- $field_string = json_encode( $fields );
252
 
253
- $args = array(
254
- 'method' => 'POST',
255
- 'body' => $field_string,
256
- 'timeout' => '5',
257
- 'redirection' => '5',
258
- 'httpversion' => '1.0',
259
- 'blocking' => true,
260
- 'headers' => $headers
261
- );
262
- $content = $mo2fApi->make_curl_call( $url, $field_string, $headers );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  return $content;
264
  }
265
 
@@ -293,62 +304,130 @@ class Customer_Setup {
293
 
294
 
295
  function validate_otp_token( $authType, $username, $transactionId, $otpToken, $cKey, $customerApiKey ) {
296
- if ( ! MO2f_Utility::is_curl_installed() ) {
297
- $message = 'Please enable curl extension. <a href="admin.php?page=mo_2fa_troubleshooting">Click here</a> for the steps to enable curl.';
298
-
299
- return json_encode( array( "status" => 'ERROR', "message" => $message ) );
300
- }
301
-
302
- $url = MO_HOST_NAME . '/moas/api/auth/validate';
303
- $mo2fApi= new Mo2f_Api();
304
- /* The customer Key provided to you */
305
- $customerKey = $cKey;
306
-
307
- /* The customer API Key provided to you */
308
- $apiKey = $customerApiKey;
309
-
310
- /* Current time in milliseconds since midnight, January 1, 1970 UTC. */
311
- $currentTimeInMillis = $mo2fApi->get_timestamp();
312
-
313
- /* Creating the Hash using SHA-512 algorithm */
314
- $stringToHash = $customerKey . $currentTimeInMillis . $apiKey;
315
- $hashValue = hash( "sha512", $stringToHash );
316
-
317
- $headers = $mo2fApi->get_http_header_array();
318
- $fields = '';
319
- if ( $authType == 'SOFT TOKEN' || $authType == 'GOOGLE AUTHENTICATOR' ) {
320
- /*check for soft token*/
321
- $fields = array(
322
- 'customerKey' => $customerKey,
323
- 'username' => $username,
324
- 'token' => $otpToken,
325
- 'authType' => $authType
326
- );
327
- } else if ( $authType == 'KBA' ) {
328
- $fields = array(
329
- 'txId' => $transactionId,
330
- 'answers' => array(
331
- array(
332
- 'question' => $otpToken[0],
333
- 'answer' => $otpToken[1]
334
- ),
335
- array(
336
- 'question' => $otpToken[2],
337
- 'answer' => $otpToken[3]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  )
339
- )
340
- );
341
- } else {
342
- //*check for otp over sms/email
343
- $fields = array(
344
- 'txId' => $transactionId,
345
- 'token' => $otpToken
346
- );
 
 
 
 
 
347
  }
348
- $field_string = json_encode( $fields );
349
-
350
-
351
- $content = $mo2fApi->make_curl_call( $url, $field_string, $headers );
352
 
353
  return $content;
354
  }
@@ -398,4 +477,4 @@ class Customer_Setup {
398
  }
399
 
400
 
401
- ?>
23
  * Contains Request Calls to Customer service.
24
  **/
25
 
26
+ include_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR.'mo2f_api.php';
27
 
28
  class Customer_Setup {
29
 
34
 
35
  private $auth_mode = 2; // miniorange test or not
36
  private $https_mode = false; // website http or https
37
+
38
 
39
  function check_customer() {
40
  $url = MO_HOST_NAME . "/moas/rest/customer/check-if-exists";
78
  );
79
 
80
 
81
+
82
  $headers = array("Content-Type"=>"application/json","charset"=>"UTF-8","Authorization"=>"Basic");
83
 
84
  $field_string = json_encode ( $fields );
85
+
86
+ $response = $mo2fApi->make_curl_call( $url, $field_string,$headers );
87
  return $response;
88
 
89
  }
204
 
205
 
206
  function send_otp_token( $uKey, $authType, $cKey, $apiKey ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
 
208
+ if(MO2F_IS_ONPREM){
209
+ include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Mo2f_OnPremRedirect.php';
210
+ $mo2fOnPremRedirect = new Mo2f_OnPremRedirect();
211
+ $content = $mo2fOnPremRedirect->OnpremSendRedirect($uKey,$authType );//change parameters as per your requirement but make sure other methods are not affected.
212
+
213
+ }else {
214
+ if ( ! MO2f_Utility::is_curl_installed() ) {
215
+ $message = 'Please enable curl extension. <a href="admin.php?page=mo_2fa_troubleshooting">Click here</a> for the steps to enable curl.';
216
+
217
+ return json_encode( array( "status" => 'ERROR', "message" => $message ) );
218
+ }
219
+
220
+ $url = MO_HOST_NAME . '/moas/api/auth/challenge';
221
+ $mo2fApi = new Mo2f_Api();
222
+ /* The customer Key provided to you */
223
+ $customerKey = $cKey;
224
+
225
+ /* The customer API Key provided to you */
226
+ $apiKey = $apiKey;
227
+
228
+ /* Current time in milliseconds since midnight, January 1, 1970 UTC. */
229
+ $currentTimeInMillis = $mo2fApi->get_timestamp();
230
+
231
+ /* Creating the Hash using SHA-512 algorithm */
232
+ $stringToHash = $customerKey . $currentTimeInMillis . $apiKey;
233
+ $hashValue = hash( "sha512", $stringToHash );
234
+
235
+ $headers = $mo2fApi->get_http_header_array();
236
+
237
+ $fields = '';
238
+ if ( $authType == 'EMAIL' || $authType == 'OUT OF BAND EMAIL' ) {
239
+ $fields = array(
240
+ 'customerKey' => $customerKey,
241
+ 'email' => $uKey,
242
+ 'authType' => $authType,
243
+ 'transactionName' => 'WordPress 2 Factor Authentication Plugin'
244
+ );
245
+ } else if ( $authType == 'SMS' ) {
246
+ $authType = "SMS";
247
+ $fields = array(
248
+ 'customerKey' => $customerKey,
249
+ 'phone' => $uKey,
250
+ 'authType' => $authType
251
+ );
252
+ } else {
253
+ $fields = array(
254
+ 'customerKey' => $customerKey,
255
+ 'username' => $uKey,
256
+ 'authType' => $authType,
257
+ 'transactionName' => 'WordPress 2 Factor Authentication Plugin'
258
+ );
259
+ }
260
+
261
+ $field_string = json_encode( $fields );
262
+
263
+ $args = array(
264
+ 'method' => 'POST',
265
+ 'body' => $field_string,
266
+ 'timeout' => '5',
267
+ 'redirection' => '5',
268
+ 'httpversion' => '1.0',
269
+ 'blocking' => true,
270
+ 'headers' => $headers
271
+ );
272
+ $content = $mo2fApi->make_curl_call( $url, $field_string, $headers );
273
+ }
274
  return $content;
275
  }
276
 
304
 
305
 
306
  function validate_otp_token( $authType, $username, $transactionId, $otpToken, $cKey, $customerApiKey ) {
307
+ $content='';
308
+ if(MO2F_IS_ONPREM){
309
+ include_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Mo2f_OnPremRedirect.php';
310
+ $mo2fOnPremRedirect = new Mo2f_OnPremRedirect();
311
+ $content = $mo2fOnPremRedirect->OnpremValidateRedirect($authType, $otpToken );
312
+ //change parameters as per your requirement but make sure other methods are not affected.
313
+
314
+ }else{
315
+
316
+ if ( ! MO2f_Utility::is_curl_installed() and !MO2F_IS_ONPREM ) {
317
+ $message = 'Please enable curl extension. <a href="admin.php?page=mo_2fa_troubleshooting">Click here</a> for the steps to enable curl.';
318
+
319
+ return json_encode( array( "status" => 'ERROR', "message" => $message ) );
320
+ }
321
+
322
+ $url = MO_HOST_NAME . '/moas/api/auth/validate';
323
+ $mo2fApi= new Mo2f_Api();
324
+ /* The customer Key provided to you */
325
+ $customerKey = $cKey;
326
+
327
+ /* The customer API Key provided to you */
328
+ $apiKey = $customerApiKey;
329
+
330
+ /* Current time in milliseconds since midnight, January 1, 1970 UTC. */
331
+ $currentTimeInMillis = $mo2fApi->get_timestamp();
332
+
333
+ /* Creating the Hash using SHA-512 algorithm */
334
+ $stringToHash = $customerKey . $currentTimeInMillis . $apiKey;
335
+ $hashValue = hash( "sha512", $stringToHash );
336
+
337
+ $headers = $mo2fApi->get_http_header_array();
338
+ $fields = '';
339
+ if ( $authType == 'SOFT TOKEN' || $authType == 'GOOGLE AUTHENTICATOR' ) {
340
+ /*check for soft token*/
341
+ $fields = array(
342
+ 'customerKey' => $customerKey,
343
+ 'username' => $username,
344
+ 'token' => $otpToken,
345
+ 'authType' => $authType
346
+ );
347
+ } else if ( $authType == 'KBA' ) {
348
+ if(MO2F_IS_ONPREM){
349
+ $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
350
+ if(isset($_POST['validate'])){
351
+ $user_id = wp_get_current_user()->ID;
352
+ }
353
+ else{
354
+ $user_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_current_user_id',$session_id_encrypt );
355
+ }
356
+ $redirect_to = isset( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : null;
357
+ $kba_ans_1 = sanitize_text_field( $_POST['mo2f_answer_1'] );
358
+ $kba_ans_2 = sanitize_text_field( $_POST['mo2f_answer_2'] );
359
+ $questions_challenged = get_user_meta($user_id ,'kba_questions_user');
360
+ $questions_challenged = $questions_challenged[0];
361
+ $all_ques_ans = (get_user_meta($user_id , 'mo2f_kba_challenge'));
362
+ $all_ques_ans = $all_ques_ans[0];
363
+ $ans_1 = $all_ques_ans[$questions_challenged[0]];
364
+ $ans_2 = $all_ques_ans[$questions_challenged[1]];
365
+ $check_trust_device = isset( $_POST['mo2f_trust_device'] ) ? $_POST['mo2f_trust_device'] : 'false';
366
+ $mo2f_rba_status = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_rba_status',$session_id_encrypt );
367
+
368
+ $pass2fa = new Miniorange_Password_2Factor_Login;
369
+ $twofa_Settings = new Miniorange_Authentication;
370
+
371
+ if(!strcmp(md5($kba_ans_1),$ans_1 ) && !strcmp(md5($kba_ans_2), $ans_2) ){
372
+ if(isset($_POST['validate'])){
373
+
374
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "COMPLETED_TEST" ) );
375
+ delete_user_meta( $user_id, 'test_2FA' );
376
+ $twofa_Settings->mo_auth_show_success_message();
377
+ }
378
+ else{
379
+ $pass2fa->mo2fa_pass2login( $redirect_to, $session_id_encrypt );
380
+ }
381
+ }
382
+ else {
383
+
384
+ if(isset($_POST['validate'])){
385
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ANSWERS" ) );
386
+ do_action('wpns_show_message', get_option( 'mo2f_message' ), 'ERROR');
387
+ }
388
+ else{
389
+ $mo2fa_login_message = 'The answers you have provided are incorrect.';
390
+ $mo2fa_login_status = 'MO_2_FACTOR_CHALLENGE_KBA_AUTHENTICATION';
391
+ $question_answers = get_user_meta($user_id , 'mo2f_kba_challenge', true);
392
+ $challenge_questions = array_keys($question_answers);
393
+ $random_keys = array_rand($challenge_questions,2);
394
+ $challenge_ques1 = $challenge_questions[$random_keys[0]];
395
+ $challenge_ques2 = $challenge_questions[$random_keys[1]];
396
+ $questions = array($challenge_ques1,$challenge_ques2);
397
+ update_user_meta( $user_id, 'kba_questions_user', $questions );
398
+ $mo2f_kbaquestions = $questions;
399
+ $pass2fa->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to,null,$session_id_encrypt);
400
+ }
401
+ }
402
+
403
+ }
404
+ else{
405
+ $fields = array(
406
+ 'txId' => $transactionId,
407
+ 'answers' => array(
408
+ array(
409
+ 'question' => $otpToken[0],
410
+ 'answer' => $otpToken[1]
411
+ ),
412
+ array(
413
+ 'question' => $otpToken[2],
414
+ 'answer' => $otpToken[3]
415
+ )
416
  )
417
+ );
418
+ }
419
+ } else {
420
+ //*check for otp over sms/email
421
+ $fields = array(
422
+ 'txId' => $transactionId,
423
+ 'token' => $otpToken
424
+ );
425
+ }
426
+ $field_string = json_encode( $fields );
427
+
428
+
429
+ $content = $mo2fApi->make_curl_call( $url, $field_string, $headers );
430
  }
 
 
 
 
431
 
432
  return $content;
433
  }
477
  }
478
 
479
 
480
+ ?>
api/class-rba-attributes.php CHANGED
@@ -23,7 +23,7 @@
23
  * Contains Request Calls to Customer service.
24
  **/
25
 
26
- include_once dirname( __FILE__ ) . '/mo2f_api.php';
27
 
28
  class Miniorange_Rba_Attributes {
29
 
@@ -134,26 +134,42 @@ class Miniorange_Rba_Attributes {
134
  }
135
 
136
  function mo2f_validate_google_auth( $useremail, $otptoken, $secret ) {
137
-
138
- if ( ! MO2f_Utility::is_curl_installed() ) {
139
- return $this->get_curl_error_message();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  }
141
 
142
-
143
- $url = MO_HOST_NAME . '/moas/api/auth/validate-google-auth-secret';
144
- $mo2fApi= new Mo2f_Api();
145
-
146
- $customerKey = get_option( 'mo2f_customerKey' );
147
- $field_string = array(
148
- 'customerKey' => $customerKey,
149
- 'username' => $useremail,
150
- 'secret' => $secret,
151
- 'otpToken' => $otptoken
152
- );
153
-
154
- $http_header_array = $mo2fApi->get_http_header_array();
155
-
156
- return $mo2fApi->make_curl_call( $url, $field_string, $http_header_array );
157
  }
158
 
159
  }
23
  * Contains Request Calls to Customer service.
24
  **/
25
 
26
+ include_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR.'mo2f_api.php';
27
 
28
  class Miniorange_Rba_Attributes {
29
 
134
  }
135
 
136
  function mo2f_validate_google_auth( $useremail, $otptoken, $secret ) {
137
+ if(MO2F_IS_ONPREM){
138
+ include_once dirname(dirname( __FILE__ )) . DIRECTORY_SEPARATOR. 'handler'.DIRECTORY_SEPARATOR. 'twofa' . DIRECTORY_SEPARATOR . 'gaonprem.php';
139
+ $gauth_obj= new Google_auth_onpremise();
140
+ $content=$gauth_obj->verifyCode($_SESSION['secret_ga'] , $otptoken );
141
+ $value = json_decode($content,true);
142
+ if($value['status'] == 'SUCCESS'){
143
+ $user = wp_get_current_user();
144
+ $user_id = $user->ID;
145
+ $gauth_obj->mo_GAuth_set_secret($user_id, $_SESSION['secret_ga']);
146
+ update_user_meta($user_id,'mo2f_2FA_method_to_configure','Google Authenticator');
147
+ update_user_meta( $user_id, 'mo2f_external_app_type', "Google Authenticator" );
148
+ update_user_meta($user_id, 'currentMethod','Google Authenticator');
149
+ }
150
+ }else{
151
+ if ( ! MO2f_Utility::is_curl_installed() ) {
152
+ return $this->get_curl_error_message();
153
+ }
154
+
155
+
156
+ $url = MO_HOST_NAME . '/moas/api/auth/validate-google-auth-secret';
157
+ $mo2fApi= new Mo2f_Api();
158
+
159
+ $customerKey = get_option( 'mo2f_customerKey' );
160
+ $field_string = array(
161
+ 'customerKey' => $customerKey,
162
+ 'username' => $useremail,
163
+ 'secret' => $secret,
164
+ 'otpToken' => $otptoken
165
+ );
166
+
167
+ $http_header_array = $mo2fApi->get_http_header_array();
168
+ $content = $mo2fApi->make_curl_call( $url, $field_string, $http_header_array );
169
  }
170
 
171
+ // return $mo2fApi->make_curl_call( $url, $field_string, $http_header_array );
172
+ return $content;
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  }
174
 
175
  }
api/class-two-factor-setup.php CHANGED
@@ -23,7 +23,7 @@
23
  * Contains Request Calls to Customer service.
24
  **/
25
 
26
- include_once dirname( __FILE__ ) . '/mo2f_api.php';
27
 
28
  class Two_Factor_Setup {
29
 
23
  * Contains Request Calls to Customer service.
24
  **/
25
 
26
+ include_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR.'mo2f_api.php';
27
 
28
  class Two_Factor_Setup {
29
 
controllers/account.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName,$Mo2fdbQueries;
4
 
5
  if ( current_user_can( 'manage_options' ) and isset( $_POST['option'] ) )
6
  {
@@ -28,19 +28,19 @@
28
  || get_option('mo_wpns_registration_status') == 'MO_OTP_DELIVERED_FAILURE') && in_array($mo2f_current_registration_status, array("MO_2_FACTOR_OTP_DELIVERED_SUCCESS", "MO_2_FACTOR_OTP_DELIVERED_FAILURE")))
29
  {
30
  $admin_phone = get_option('mo_wpns_admin_phone') ? get_option('mo_wpns_admin_phone') : "";
31
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'account'.DIRECTORY_SEPARATOR.'verify.php';
32
  }
33
  else if ((get_option ( 'mo_wpns_verify_customer' ) == 'true' || (get_option('mo2f_email') && !get_option('mo2f_customerKey'))) && $mo2f_current_registration_status == "MO_2_FACTOR_VERIFY_CUSTOMER")
34
  {
35
  $admin_email = get_option('mo2f_email') ? get_option('mo2f_email') : "";
36
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'account'.DIRECTORY_SEPARATOR.'login.php';
37
  }
38
  else if (! $moWpnsUtility->icr())
39
  {
40
  delete_option ( 'password_mismatch' );
41
  update_option ( 'mo_wpns_new_registration', 'true' );
42
  $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'REGISTRATION_STARTED' ) );
43
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'account'.DIRECTORY_SEPARATOR.'register.php';
44
  }
45
  else
46
  {
@@ -48,7 +48,7 @@
48
  $key = get_option('mo2f_customerKey');
49
  $api = get_option('mo2f_api_key');
50
  $token = get_option('mo2f_customer_token');
51
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'account'.DIRECTORY_SEPARATOR.'profile.php';
52
  }
53
 
54
 
@@ -95,7 +95,6 @@
95
 
96
  $customer = new MocURL();
97
  $content = json_decode($customer->check_customer($email), true);
98
-
99
  $Mo2fdbQueries->insert_user( $user->ID );
100
  switch ($content['status'])
101
  {
@@ -216,7 +215,6 @@
216
  update_option( 'mo_wpns_enable_log_requests' , true );
217
  update_option( 'mo2f_miniorange_admin', $user->ID );
218
  update_option( 'mo_2factor_admin_registration_status', 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' );
219
- // update_option( 'mo_2factor_admin_registration_status', 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' );
220
  $Mo2fdbQueries->insert_user( $user->ID );
221
  $Mo2fdbQueries->update_user_details( $user->ID, array(
222
  'mo2f_EmailVerification_config_status' => get_option( 'mo2f_is_NC' ) == 0 ? true : false,
@@ -226,7 +224,6 @@
226
  'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS'
227
  ) );
228
  $enduser = new Two_Factor_Setup();
229
-
230
  $userinfo = json_decode( $enduser->mo2f_get_userinfo( $email ), true );
231
  $mo2f_second_factor = 'NONE';
232
  if ( json_last_error() == JSON_ERROR_NONE ) {
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName,$Mo2fdbQueries;
4
 
5
  if ( current_user_can( 'manage_options' ) and isset( $_POST['option'] ) )
6
  {
28
  || get_option('mo_wpns_registration_status') == 'MO_OTP_DELIVERED_FAILURE') && in_array($mo2f_current_registration_status, array("MO_2_FACTOR_OTP_DELIVERED_SUCCESS", "MO_2_FACTOR_OTP_DELIVERED_FAILURE")))
29
  {
30
  $admin_phone = get_option('mo_wpns_admin_phone') ? get_option('mo_wpns_admin_phone') : "";
31
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'account'.DIRECTORY_SEPARATOR.'verify.php';
32
  }
33
  else if ((get_option ( 'mo_wpns_verify_customer' ) == 'true' || (get_option('mo2f_email') && !get_option('mo2f_customerKey'))) && $mo2f_current_registration_status == "MO_2_FACTOR_VERIFY_CUSTOMER")
34
  {
35
  $admin_email = get_option('mo2f_email') ? get_option('mo2f_email') : "";
36
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'account'.DIRECTORY_SEPARATOR.'login.php';
37
  }
38
  else if (! $moWpnsUtility->icr())
39
  {
40
  delete_option ( 'password_mismatch' );
41
  update_option ( 'mo_wpns_new_registration', 'true' );
42
  $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo_2factor_user_registration_status' => 'REGISTRATION_STARTED' ) );
43
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'account'.DIRECTORY_SEPARATOR.'register.php';
44
  }
45
  else
46
  {
48
  $key = get_option('mo2f_customerKey');
49
  $api = get_option('mo2f_api_key');
50
  $token = get_option('mo2f_customer_token');
51
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'account'.DIRECTORY_SEPARATOR.'profile.php';
52
  }
53
 
54
 
95
 
96
  $customer = new MocURL();
97
  $content = json_decode($customer->check_customer($email), true);
 
98
  $Mo2fdbQueries->insert_user( $user->ID );
99
  switch ($content['status'])
100
  {
215
  update_option( 'mo_wpns_enable_log_requests' , true );
216
  update_option( 'mo2f_miniorange_admin', $user->ID );
217
  update_option( 'mo_2factor_admin_registration_status', 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' );
 
218
  $Mo2fdbQueries->insert_user( $user->ID );
219
  $Mo2fdbQueries->update_user_details( $user->ID, array(
220
  'mo2f_EmailVerification_config_status' => get_option( 'mo2f_is_NC' ) == 0 ? true : false,
224
  'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS'
225
  ) );
226
  $enduser = new Two_Factor_Setup();
 
227
  $userinfo = json_decode( $enduser->mo2f_get_userinfo( $email ), true );
228
  $mo2f_second_factor = 'NONE';
229
  if ( json_last_error() == JSON_ERROR_NONE ) {
controllers/advanced-blocking.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
  if(current_user_can( 'manage_options' ) && isset($_POST['option']) )
6
  {
@@ -37,6 +37,25 @@
37
  $referrers = get_option( 'mo_wpns_referrers');
38
  $referrers = explode(";",$referrers);
39
  $current_browser= $moWpnsUtility->getCurrentBrowser();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  switch($current_browser)
42
  {
@@ -54,7 +73,7 @@
54
  $block_opera = 'disabled'; break;
55
  }
56
 
57
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'advanced-blocking.php';
58
 
59
 
60
  /* ADVANCD BLOCKING FUNCTIONS */
@@ -65,31 +84,30 @@
65
  $flag=0;
66
  $max_allowed_ranges = 100;
67
  $added_mappings_ranges = 0 ;
68
- for($i=1;$i<=$max_allowed_ranges;$i++)
69
- {
70
- if(isset($postedValue['range_'.$i]) && !empty($postedValue['range_'.$i]))
71
- {
72
- $range_array = explode("-",$postedValue['range_'.$i]);
73
- if(sizeof($range_array) == 2){
74
- $lowerIP = trim($range_array[0]);
75
- $higherIP = trim($range_array[1]);
76
- if(filter_var($lowerIP, FILTER_VALIDATE_IP) && filter_var($higherIP, FILTER_VALIDATE_IP)){
77
- $added_mappings_ranges++;
78
- update_option( 'mo_wpns_iprange_range_'.$added_mappings_ranges, $postedValue['range_'.$i]);
79
- }else{
80
- //error message of invalid IP
81
- $flag=1;
82
- do_action('wpns_show_message',MoWpnsMessages::showMessage('INVALID_IP'),'ERROR');
83
- break;
84
- }
85
- }else{
86
- //error message of invalid format
87
- $flag=1;
88
- do_action('wpns_show_message',MoWpnsMessages::showMessage('INVALID_IP_FORMAT'),'ERROR');
89
- break;
90
  }
 
 
 
 
 
91
  }
92
- }
 
 
93
  if($added_mappings_ranges==0)
94
  update_option( 'mo_wpns_iprange_range_1','');
95
  update_option( 'mo_wpns_iprange_count', $added_mappings_ranges);
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
  if(current_user_can( 'manage_options' ) && isset($_POST['option']) )
6
  {
37
  $referrers = get_option( 'mo_wpns_referrers');
38
  $referrers = explode(";",$referrers);
39
  $current_browser= $moWpnsUtility->getCurrentBrowser();
40
+ $start = array();
41
+ $end = array();
42
+ for($i = 1 ; $i <= $range_count ; $i++){
43
+ $ip_range = get_option("mo_wpns_iprange_range_".$i);
44
+ if($ip_range){
45
+ $a = explode('-', $ip_range);
46
+ /*$start = array();
47
+ $end = array();*/
48
+ $start[$i] = $a[0];
49
+ $end[$i] = $a[1];
50
+ }
51
+
52
+ }
53
+ if(!isset($start[1])){
54
+ $start[1] = '';
55
+ }
56
+ if(!isset($end[1])){
57
+ $end[1] = '';
58
+ }
59
 
60
  switch($current_browser)
61
  {
73
  $block_opera = 'disabled'; break;
74
  }
75
 
76
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'advanced-blocking.php';
77
 
78
 
79
  /* ADVANCD BLOCKING FUNCTIONS */
84
  $flag=0;
85
  $max_allowed_ranges = 100;
86
  $added_mappings_ranges = 0 ;
87
+ for($i=1;$i<=$max_allowed_ranges;$i++){
88
+ if(isset($postedValue['start_'.$i]) && isset($postedValue['end_'.$i]) && !empty($postedValue['start_'.$i]) && !empty($postedValue['end_'.$i])){
89
+
90
+ $postedValue['start_'.$i] = sanitize_text_field($postedValue['start_'.$i]);
91
+ $postedValue['end_'.$i] = sanitize_text_field($postedValue['end_'.$i]);
92
+
93
+ if(filter_var($postedValue['start_'.$i] , FILTER_VALIDATE_IP ) && filter_var($postedValue['end_'.$i] , FILTER_VALIDATE_IP ) && (ip2long($postedValue['end_'.$i]) > ip2long($postedValue['start_'.$i])) ){
94
+ $range = '';
95
+ $range = $postedValue['start_'.$i];
96
+ $range .= '-';
97
+ $range .= $postedValue['end_'.$i];
98
+ $added_mappings_ranges++;
99
+ update_option( 'mo_wpns_iprange_range_'.$added_mappings_ranges, $range );
100
+
 
 
 
 
 
 
 
 
101
  }
102
+ else{
103
+ $flag = 1;
104
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('INVALID_IP'),'ERROR');
105
+ return;
106
+ }
107
  }
108
+ }
109
+
110
+
111
  if($added_mappings_ranges==0)
112
  update_option( 'mo_wpns_iprange_range_1','');
113
  update_option( 'mo_wpns_iprange_count', $added_mappings_ranges);
controllers/backup.php DELETED
@@ -1,79 +0,0 @@
1
- <?php
2
-
3
- global $moWpnsUtility,$dirName;
4
-
5
- $img_loader_url = plugins_url('wp-security-pro/includes/images/loader.gif');
6
- $page_url = "";
7
- $message = '<div id=\'backupmessage\'><h2>DO NOT :</h2><ol><li>Close this browser</li><li>Reload this page</li><li>Click the Stop or Back button.</li></ol><h2>Untill your database backup is completed</h2></div><br/><div class=\'backupmessage\'><h2><div id=\'inprogress\'>DATABASE BACKUP IN PROGRESS</div></h2></div><div id=\'dbloader\' ><img src=\"'.$img_loader_url.'\"></div>';
8
- $message2a = 'Database Backup is Completed. Check <b><i>';
9
- $message2b = '</i></b>file in db-backups folder.';
10
-
11
- update_site_option('mo2f_visit_backup',true);
12
-
13
- if(current_user_can( 'manage_options' ) && isset($_POST['option']))
14
- {
15
- switch($_POST['option'])
16
- {
17
- case "mo2f_enable_cron_backup":
18
- wpns_handle_db_enable_form($_POST); break;
19
- case "mo2f_cron_backup_configuration":
20
- wpns_handle_db_configuration_form($_POST); break;
21
- case "mo2f_enable_cron_file_backup":
22
- wpns_handle_file_backup_enable_form($_POST); break;
23
- }
24
- }
25
-
26
-
27
-
28
-
29
- function wpns_handle_db_enable_form($postData){
30
- if(! get_option('mo2f_cron_hours')){
31
- update_option('mo2f_cron_hours', 43200);
32
- }
33
- $enable = isset($postData['mo2f_enable_cron_backup_timely']) ? $postData['mo2f_enable_cron_backup_timely'] : '0';
34
- update_option( 'mo2f_enable_cron_backup', $enable );
35
- if(get_option('mo2f_enable_cron_backup') == '0'){
36
- $handler_obj = new site_backup;
37
- $handler_obj->bl_deactivate();
38
- do_action('wpns_show_message',MoWpnsMessages::showMessage('CRON_DB_BACKUP_DISABLE'),'ERROR');
39
- }else{
40
- do_action('wpns_show_message',MoWpnsMessages::showMessage('CRON_DB_BACKUP_ENABLE'),'SUCCESS');
41
- }
42
- }
43
-
44
- function wpns_handle_db_configuration_form($postData){
45
- $mo2f_cron_hours = $postData['mo2f_cron_hours'] * 60 *60;
46
- if($mo2f_cron_hours < 3600){
47
- do_action('wpns_show_message',MoWpnsMessages::showMessage('INVALID_HOURS'),'ERROR');
48
- }else{
49
- update_option('mo2f_cron_hours', $mo2f_cron_hours);
50
- $mo2f_enable_cron_backup =get_option('mo2f_enable_cron_backup',true);
51
- if(isset($mo2f_enable_cron_backup) && $mo2f_enable_cron_backup=='1'){
52
- $handler_obj = new site_backup;
53
- $handler_obj->bl_deactivate();
54
- if ( ! wp_next_scheduled( 'bl_cron_hook' ) ) {
55
- wp_schedule_event( time(), 'db_backup_time', 'bl_cron_hook' );
56
- }
57
- do_action('wpns_show_message',MoWpnsMessages::showMessage('CONFIG_SAVED'),'SUCCESS');
58
- }
59
- }
60
- }
61
-
62
- function wpns_handle_file_backup_enable_form($postData){
63
- if(! get_option('mo2f_cron_file_backup_hours')){
64
- update_option('mo2f_cron_file_backup_hours', 43200);
65
- }
66
- $enable = isset($postData['mo2f_enable_cron_file_backup_timely']) ? $postData['mo2f_enable_cron_file_backup_timely'] : '0';
67
- update_option( 'mo2f_enable_cron_file_backup', $enable );
68
- if(get_option('mo2f_enable_cron_file_backup') == '0'){
69
- $handler_obj = new site_backup;
70
- $handler_obj->file_backup_deactivate();
71
- do_action('wpns_show_message',MoWpnsMessages::showMessage('CRON_FILE_BACKUP_DISABLE'),'ERROR');
72
- }
73
- else{
74
- do_action('wpns_show_message',MoWpnsMessages::showMessage('CRON_FILE_BACKUP_ENABLE'),'SUCCESS');
75
- }
76
- }
77
-
78
-
79
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'backup.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
controllers/backup/backup.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ include $mo2f_dirName. 'views'.DIRECTORY_SEPARATOR.'backup'.DIRECTORY_SEPARATOR.'backup.php';
controllers/backup/backup_ajax.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Mo_wpns_file_db_backup{
3
+
4
+ function __construct(){
5
+ add_action( 'admin_init' , array( $this, 'mo_wpns_file_db_backup_functions' ) );
6
+ }
7
+
8
+ public function mo_wpns_file_db_backup_functions(){
9
+ add_action('wp_ajax_mo_wpns_backup_redirect', array( $this, 'mo_wpns_backup_redirect' ));
10
+ }
11
+
12
+ public function mo_wpns_backup_redirect(){
13
+
14
+ switch($_POST['call_type'])
15
+ {
16
+ case "submit_backup_settings_form":
17
+ $this->mo_wpns_save_backup_config_form($_POST);
18
+ break;
19
+ case "submit_schedule_settings_form":
20
+ $this->mo_wpns_save_schedule_backup_config_form($_POST);
21
+ break;
22
+ case "delete_backup":
23
+ $this->delete_backup($_POST);
24
+ break;
25
+ }
26
+ }
27
+
28
+ public function mo_wpns_save_backup_config_form($postData){
29
+ $nonce = $postData['nonce'];
30
+ if ( ! wp_verify_nonce( $nonce, 'wpns-backup-settings' ) ){
31
+ wp_send_json('ERROR');
32
+ }
33
+
34
+ if(! isset($postData['backup_plugin']) && ! isset($postData['backup_themes']) && ! isset($postData['backup_wp_files']) && ! isset($postData['database'])){
35
+ wp_send_json('folder_error');
36
+ }
37
+
38
+ isset($postData['backup_plugin']) ? update_site_option( 'mo_file_manual_backup_plugins', sanitize_text_field($postData['backup_plugin'])) : update_site_option( 'mo_file_manual_backup_plugins', 0);
39
+
40
+ isset($postData['backup_themes']) ? update_site_option( 'mo_file_manual_backup_themes', sanitize_text_field($postData['backup_themes'])) : update_site_option( 'mo_file_manual_backup_themes', 0);
41
+
42
+ isset($postData['backup_wp_files']) ? update_site_option( 'mo_file_manual_backup_wp_files', sanitize_text_field($postData['backup_wp_files'])) : update_site_option( 'mo_file_manual_backup_wp_files', 0);
43
+
44
+ isset($postData['database']) ? update_site_option( 'mo_database_backup', sanitize_text_field($postData['database'])) : update_site_option( 'mo_database_backup', 0);
45
+
46
+ if(isset($postData['backup_plugin']) || isset($postData['backup_themes']) || isset($postData['backup_wp_files'])){
47
+ $handler_obj = new MoBackupSite();
48
+ update_site_option('file_backup_created_time',date("l").' , '.date("d-m-Y") .' '.date("h:i"));
49
+ $handler_obj->file_manual_backup();
50
+ }
51
+ if(isset($postData['database'])) {
52
+ $handler_obj = new MoBackupSite();
53
+ update_site_option('db_backup_created_time',date("l").' , '.date("d-m-Y") .' '.date("h:i"));
54
+ $handler_obj->backupDB();
55
+ }
56
+ wp_send_json('created_backup');
57
+ }
58
+
59
+ function mo_wpns_save_schedule_backup_config_form($postData){
60
+ $nonce = $postData['nonce'];
61
+ if ( ! wp_verify_nonce( $nonce, 'wpns-schedule-backup' ) ){
62
+ wp_send_json('ERROR');
63
+
64
+ }
65
+
66
+ $handler_obj = new MoBackupSite;
67
+ if(!isset($postData['backup_plugin']) && ! isset($postData['backup_themes']) && ! isset($postData['backup_wp_files']) && ! isset($postData['database']))
68
+ {
69
+ wp_send_json('folder_error');
70
+
71
+ }
72
+
73
+ isset($postData['backup_plugin']) ? update_site_option( 'mo_file_backup_plugins', sanitize_text_field($postData['backup_plugin'])) : update_site_option( 'mo_file_backup_plugins', 0);
74
+
75
+ isset($postData['backup_themes']) ? update_site_option( 'mo_file_backup_themes', sanitize_text_field($postData['backup_themes'])) : update_site_option( 'mo_file_backup_themes', 0);
76
+
77
+ isset($postData['backup_wp_files']) ? update_site_option( 'mo_file_backup_wp_files', sanitize_text_field($postData['backup_wp_files'])) : update_site_option( 'mo_file_backup_wp_files', 0);
78
+
79
+ isset($postData['database']) ? update_site_option( 'mo_schedule_database_backup', sanitize_text_field($postData['database'])) : update_site_option( 'mo_schedule_database_backup', 0);
80
+
81
+ if($postData['backup_time']==='12'||$postData['backup_time']==='24'||$postData['backup_time']==='168'||$postData['backup_time']==='360'||$postData['backup_time']==='720')
82
+ {
83
+ isset($postData['backup_time']) ? update_site_option( 'mo_wpns_backup_time', sanitize_text_field($postData['backup_time'])) : update_site_option( 'mo_wpns_backup_time', 0);
84
+ }else{
85
+ wp_send_json('invalid_hours');
86
+
87
+ }
88
+
89
+ isset($postData['enable_backup_schedule']) ? update_site_option( 'enable_backup_schedule', sanitize_text_field($postData['enable_backup_schedule'])) : update_site_option( 'enable_backup_schedule', 0);
90
+
91
+ isset($postData['local_storage']) ? update_site_option( 'storage_type', sanitize_text_field($postData['local_storage'])) : update_site_option( 'storage_type', 0);
92
+
93
+ if(get_site_option('enable_backup_schedule') === '1'){
94
+
95
+ if(isset($postData['backup_plugin']) || isset($postData['backup_themes']) || isset($postData['backup_wp_files'])){
96
+ $handler_obj-> file_backup_deactivate();
97
+ if (!wp_next_scheduled( 'mo_eb_file_cron_hook')) {
98
+ wp_schedule_event( time(), 'file_eb_backup_time', 'mo_eb_file_cron_hook' );
99
+ }
100
+ update_site_option('file_backup_created_time',date("l").' , '.date("d-m-Y") .' '.date("h:i"));
101
+ update_site_option('scheduled_file_backup',1);
102
+ }
103
+ else
104
+ $handler_obj-> file_backup_deactivate();
105
+
106
+ if(get_site_option('mo_schedule_database_backup') === '1'){
107
+ $handler_obj->bl_deactivate();
108
+ if ( ! wp_next_scheduled( 'mo_eb_bl_cron_hook' ) ) {
109
+ wp_schedule_event( time(), 'db_eb_backup_time', 'mo_eb_bl_cron_hook' );
110
+ }
111
+ update_site_option('db_backup_created_time',date("l").' , '.date("d-m-Y") .' '.date("h:i"));
112
+ update_site_option('scheduled_db_backup',1);
113
+ }
114
+ else
115
+ $handler_obj->bl_deactivate();
116
+
117
+ wp_send_json('success');
118
+
119
+ }else{
120
+ $handler_obj-> file_backup_deactivate();
121
+ $handler_obj->bl_deactivate();
122
+ update_site_option('scheduled_db_backup',0);
123
+ update_site_option('scheduled_file_backup',0);
124
+ wp_send_json('disable');
125
+
126
+ }
127
+ }
128
+
129
+
130
+
131
+ function delete_backup($postData){
132
+
133
+ $nonce = $postData['nonce'];
134
+ if ( ! wp_verify_nonce( $nonce, 'delete_entry' ) ){
135
+ wp_send_json('ERROR');
136
+
137
+ }
138
+
139
+ if(current_user_can('administrator')){
140
+ global $wpnsDbQueries;
141
+ $id = $postData['id'];
142
+ $row_exist = (int)$wpnsDbQueries->row_exist($id);
143
+ $status = file_exists($postData["folder_name"].DIRECTORY_SEPARATOR. $postData['file_name']);
144
+ if($status){
145
+ unlink($postData["folder_name"].DIRECTORY_SEPARATOR. $postData['file_name']);
146
+ if($row_exist)
147
+ $wpnsDbQueries->delete_file($id);
148
+ wp_send_json('success');
149
+
150
+ }else{
151
+ $wpnsDbQueries->delete_file($id);
152
+ wp_send_json('notexist');
153
+ }
154
+ }
155
+ }
156
+ }new Mo_wpns_file_db_backup();
157
+ ?>
controllers/backup/backup_controller.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'backup'.DIRECTORY_SEPARATOR.'backup_setting_view.php';
controllers/backup/backup_created_report.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'backup'.DIRECTORY_SEPARATOR.'backup_created_report.php';
controllers/backup/backup_created_result.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function showBackupResults(){
3
+ global $wpnsDbQueries;
4
+ $array = $wpnsDbQueries->get_table_content();
5
+ $array_size = sizeof($array);
6
+ for($i=0; $i<(int)$array_size; $i++){
7
+ $backup_file_path = $array[$i]->plugin_path.DIRECTORY_SEPARATOR.$array[$i]->file_name;
8
+ if(file_exists($backup_file_path))
9
+ show_backup_report($array[$i]->plugin_path, $array[$i]->file_name, $array[$i]->created_timestamp,$array[$i]->id);
10
+ else
11
+ $wpnsDbQueries->delete_file($array[$i]->id);
12
+ }
13
+ }
14
+ ?>
controllers/backup/backup_schdule.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $file_backup_time =get_site_option('file_backup_created_time');
4
+ $db_eb_backup_time = get_site_option('db_backup_created_time');
5
+ $file_schedule_status = get_site_option('scheduled_file_backup');
6
+ $db_backup_status = get_site_option('scheduled_db_backup');
7
+ $next_file_backup_hours = get_site_option('mo_wpns_backup_time');
8
+ $next_db_backup_hours = get_site_option('mo_wpns_backup_time');
9
+ $img_loader_url = plugins_url('backup-wordpress'.DIRECTORY_SEPARATOR .'includes'.DIRECTORY_SEPARATOR .'images'.DIRECTORY_SEPARATOR .'loader.gif');
10
+ $page_url = "";
11
+ $file_next_backup_timestamp = wp_next_scheduled( 'mo_eb_file_cron_hook' );
12
+ $db_next_backup_timestamp = wp_next_scheduled( 'mo_eb_bl_cron_hook' );
13
+
14
+ $file_date = date('d-m-Y', $file_next_backup_timestamp);
15
+ $file_time = date('H:i', $file_next_backup_timestamp);
16
+ $file_day = date('l',$file_next_backup_timestamp);
17
+
18
+ $db_date = date('d-m-Y', $db_next_backup_timestamp);
19
+ $db_time = date('H:i', $db_next_backup_timestamp);
20
+ $db_day = date('l',$db_next_backup_timestamp);
21
+
22
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'backup'.DIRECTORY_SEPARATOR.'backup_schdule.php';
controllers/backup_ajax.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
- class wpns_backup_ajax
3
- {
4
- function __construct(){
5
-
6
- add_action( 'admin_init' , array( $this, 'mo_wpns_backup' ) );
7
- }
8
-
9
- function mo_wpns_backup(){
10
-
11
- add_action( 'wp_ajax_mo_wpns_backup_ajax', array($this,'mo_wpns_backup_ajax') );
12
- }
13
-
14
- function mo_wpns_backup_ajax(){
15
-
16
- switch ($_POST['mo_wpns_backup_ajax_forms'])
17
- {
18
- case 'wpns_filebackup_form':
19
- $this->handle_save_backup_config($_POST); break;
20
- case 'wpns_instant_backup':
21
- $this->instant_backup($_POST); break;
22
-
23
-
24
-
25
- }
26
- }
27
- function instant_backup($postData){
28
- if(! isset($postData['backup_plugin']) && ! isset($postData['backup_themes']) && ! isset($postData['backup_wp_files'])){
29
- wp_send_json('folder_error');
30
- return;
31
- }else{
32
- $handler_obj = new site_backup;
33
- $handler_obj->file_cron_backup();
34
- wp_send_json('success');
35
- return;
36
- }
37
- }
38
-
39
- function handle_save_backup_config($postData){
40
- if(! isset($postData['backup_plugin']) && ! isset($postData['backup_themes']) && ! isset($postData['backup_wp_files'])){
41
- wp_send_json('folder_error');
42
- return;
43
- }
44
-
45
- $handler_obj = new site_backup;
46
- isset($postData['backup_plugin']) ? update_option( 'mo_file_backup_plugins', sanitize_text_field($postData['backup_plugin'])) : update_option( 'mo_file_backup_plugins', 0);
47
- isset($postData['backup_themes']) ? update_option( 'mo_file_backup_themes', sanitize_text_field($postData['backup_themes'])) : update_option( 'mo_file_backup_themes', 0);
48
- isset($postData['backup_wp_files']) ? update_option( 'mo_file_backup_wp_files', sanitize_text_field($postData['backup_wp_files'])) : update_option( 'mo_file_backup_wp_files', 0);
49
-
50
- if(isset($postData['file_backup_hour'])){
51
- $mo2f_cron_file_backup_hours = $postData['file_backup_hour'] * 60 *60;
52
- if($mo2f_cron_file_backup_hours < 3600){
53
- wp_send_json('invalid_hours');
54
- return;
55
- }else{
56
- update_option('mo2f_cron_file_backup_hours', $mo2f_cron_file_backup_hours);
57
- $handler_obj-> file_backup_deactivate();
58
- if (!wp_next_scheduled( 'file_cron_hook')) {
59
- wp_schedule_event( time(), 'cron_backup_time', 'file_cron_hook' );
60
- }
61
- wp_send_json('schedule_backup');
62
- return;
63
- }
64
- }else{
65
- $handler_obj->file_cron_backup();
66
-
67
- wp_send_json('manual_backup');
68
- return;
69
- }
70
-
71
- }
72
- }
73
- new wpns_backup_ajax();
74
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
controllers/change-password.php CHANGED
@@ -1,13 +1,13 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
  $username = $user->data->user_login;
6
  $message = isset($newpassword) && ($newpassword != $confirmpassword) ? "Both Passwords do not match." : "Please enter a stronger password.";
7
- $css_file = plugins_url('wp-security-pro/includes/css/style_settings.css',$dirName);
8
- $js_file = plugins_url('wp-security-pro/includes/js/settings_page.js',$dirName);
9
  $js_url = 'https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js';
10
 
11
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'change-password.php';
12
  exit;
13
 
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
  $username = $user->data->user_login;
6
  $message = isset($newpassword) && ($newpassword != $confirmpassword) ? "Both Passwords do not match." : "Please enter a stronger password.";
7
+ $css_file = plugins_url('wp-security-pro/includes/css/style_settings.css',$mo2f_dirName);
8
+ $js_file = plugins_url('wp-security-pro/includes/js/settings_page.js',$mo2f_dirName);
9
  $js_url = 'https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js';
10
 
11
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'change-password.php';
12
  exit;
13
 
controllers/content-protection.php CHANGED
@@ -1,10 +1,9 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
-
5
 
6
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
7
- {
8
  switch($_POST['option'])
9
  {
10
  case "mo_wpns_content_protection":
@@ -25,12 +24,13 @@ $disable_file_editing = get_option('mo2f_disable_file_editing') ? "checke
25
  $comment_spam_protect = get_option('mo_wpns_enable_comment_spam_blocking') ? "checked" : "";
26
  $enable_recaptcha = get_option('mo_wpns_enable_comment_recaptcha') ? "checked" : "";
27
  $htaccess_file = get_option('mo2f_htaccess_file') ? "checked" : "";
28
-
29
  $test_recaptcha_url = "";
30
  $wp_config = site_url().'/wp-config.php';
31
  $wp_uploads = get_site_url().'/wp-content/uploads';
32
  $plugin_editor = get_site_url().'/wp-admin/plugin-editor.php';
33
-
 
34
  if($enable_recaptcha)
35
  {
36
  $test_recaptcha_url = add_query_arg( array('option'=>'testrecaptchaconfig'), $_SERVER['REQUEST_URI'] );
@@ -38,17 +38,26 @@ if($enable_recaptcha)
38
  $captcha_secret_key = get_option('mo_wpns_recaptcha_secret_key');
39
  }
40
 
41
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'content-protection.php';
42
 
43
  /* CONTENT PROTECTION FUNCTIONS */
44
 
45
  //Function to save content protection settings
46
  function wpns_handle_content_protection()
47
- {
48
  isset($_POST['protect_wp_config']) ? update_option('mo2f_protect_wp_config' , $_POST['protect_wp_config']) : update_option('mo2f_protect_wp_config' ,0);
49
  isset($_POST['prevent_directory_browsing']) ? update_option('mo2f_prevent_directory_browsing', $_POST['prevent_directory_browsing']): update_option('mo2f_prevent_directory_browsing',0);
50
  isset($_POST['disable_file_editing']) ? update_option('mo2f_disable_file_editing' , $_POST['disable_file_editing']) : update_option('mo2f_disable_file_editing' ,0);
51
  isset($_POST['mo2f_htaccess_file']) ? update_option('mo2f_htaccess_file' , $_POST['mo2f_htaccess_file']) : update_option('mo2f_htaccess_file',0);
 
 
 
 
 
 
 
 
 
52
 
53
  $mo_wpns_htaccess_handler = new MoWpnsHandler();
54
  $mo_wpns_htaccess_handler->update_htaccess_configuration();
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
 
4
 
5
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
6
+ {
7
  switch($_POST['option'])
8
  {
9
  case "mo_wpns_content_protection":
24
  $comment_spam_protect = get_option('mo_wpns_enable_comment_spam_blocking') ? "checked" : "";
25
  $enable_recaptcha = get_option('mo_wpns_enable_comment_recaptcha') ? "checked" : "";
26
  $htaccess_file = get_option('mo2f_htaccess_file') ? "checked" : "";
27
+ $restAPI = get_option('mo2f_restrict_restAPI') ? "checked" : "";
28
  $test_recaptcha_url = "";
29
  $wp_config = site_url().'/wp-config.php';
30
  $wp_uploads = get_site_url().'/wp-content/uploads';
31
  $plugin_editor = get_site_url().'/wp-admin/plugin-editor.php';
32
+ $restAPI_link = rest_url().'wp'.DIRECTORY_SEPARATOR.'v2'.DIRECTORY_SEPARATOR.'users';
33
+ $restApiPlugin = 'https:'.DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR.'www.wordpress.org'.DIRECTORY_SEPARATOR.'plugins'.DIRECTORY_SEPARATOR.'wp-rest-api-authentication';
34
  if($enable_recaptcha)
35
  {
36
  $test_recaptcha_url = add_query_arg( array('option'=>'testrecaptchaconfig'), $_SERVER['REQUEST_URI'] );
38
  $captcha_secret_key = get_option('mo_wpns_recaptcha_secret_key');
39
  }
40
 
41
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'content-protection.php';
42
 
43
  /* CONTENT PROTECTION FUNCTIONS */
44
 
45
  //Function to save content protection settings
46
  function wpns_handle_content_protection()
47
+ {
48
  isset($_POST['protect_wp_config']) ? update_option('mo2f_protect_wp_config' , $_POST['protect_wp_config']) : update_option('mo2f_protect_wp_config' ,0);
49
  isset($_POST['prevent_directory_browsing']) ? update_option('mo2f_prevent_directory_browsing', $_POST['prevent_directory_browsing']): update_option('mo2f_prevent_directory_browsing',0);
50
  isset($_POST['disable_file_editing']) ? update_option('mo2f_disable_file_editing' , $_POST['disable_file_editing']) : update_option('mo2f_disable_file_editing' ,0);
51
  isset($_POST['mo2f_htaccess_file']) ? update_option('mo2f_htaccess_file' , $_POST['mo2f_htaccess_file']) : update_option('mo2f_htaccess_file',0);
52
+ if(isset($_POST['restrictAPI'])){
53
+ update_option('mo2f_restrict_restAPI', 1);
54
+ }
55
+ else{
56
+ update_option('mo2f_restrict_restAPI',0);
57
+ }
58
+
59
+
60
+
61
 
62
  $mo_wpns_htaccess_handler = new MoWpnsHandler();
63
  $mo_wpns_htaccess_handler->update_htaccess_configuration();
controllers/dashboard.php CHANGED
@@ -20,4 +20,4 @@
20
  $total_malicious=($total_malicious/1000);
21
  $total_malicious= round($total_malicious,1)."k";
22
  }
23
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'dashboard.php';
20
  $total_malicious=($total_malicious/1000);
21
  $total_malicious= round($total_malicious,1)."k";
22
  }
23
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'dashboard.php';
controllers/dashboard_ajax.php CHANGED
@@ -12,34 +12,35 @@ class Mo2f_ajax_dashboard
12
  update_site_option('mo_2f_switch_all', 1);
13
  else if($tab_count == 0)
14
  update_site_option('mo_2f_switch_all', 0);
 
15
  switch($_POST['option'])
16
  {
17
  case "tab_all_switch":
18
- $this->mo2f_handle_all_enable(isset($_POST['switch_val']));
19
  break;
20
  case "tab_2fa_switch":
21
- $this->mo2f_handle_2fa_enable(isset($_POST['switch_val']));
22
  break;
23
  case "tab_waf_switch":
24
- $this->mo2f_handle_waf_enable(isset($_POST['switch_val']));
25
  break;
26
  case "tab_login_switch":
27
- $this->mo2f_handle_login_enable(isset($_POST['switch_val']));
28
  break;
29
  case "tab_backup_switch":
30
- $this->mo2f_handle_backup_enable(isset($_POST['switch_val']));
31
  break;
32
  case "tab_malware_switch":
33
- $this->mo2f_handle_malware_enable(isset($_POST['switch_val']));
34
  break;
35
  case "tab_block_switch":
36
- $this->mo2f_handle_block_enable(isset($_POST['switch_val']));
37
  break;
38
  case "tab_report_switch":
39
- $this->mo2f_handle_report_enable(isset($_POST['switch_val']));
40
  break;
41
  case "tab_notif_switch":
42
- $this->mo2f_handle_notif_enable(isset($_POST['switch_val']));
43
  break;
44
  }
45
  }
@@ -150,7 +151,7 @@ class Mo2f_ajax_dashboard
150
  else{
151
  update_site_option('mo_2f_switch_backup', 0);
152
  update_site_option('mo2f_tab_count', get_site_option('mo2f_tab_count')-1);
153
- $handler_obj = new site_backup;
154
  $handler_obj->bl_deactivate();
155
  update_site_option('mo2f_enable_cron_backup', 0);
156
  $handler_obj->file_backup_deactivate();
12
  update_site_option('mo_2f_switch_all', 1);
13
  else if($tab_count == 0)
14
  update_site_option('mo_2f_switch_all', 0);
15
+ $santizied_post=isset($_POST['switch_val'])? sanitize_text_field($_POST['switch_val']):null;
16
  switch($_POST['option'])
17
  {
18
  case "tab_all_switch":
19
+ $this->mo2f_handle_all_enable($santizied_post);
20
  break;
21
  case "tab_2fa_switch":
22
+ $this->mo2f_handle_2fa_enable($santizied_post);
23
  break;
24
  case "tab_waf_switch":
25
+ $this->mo2f_handle_waf_enable($santizied_post);
26
  break;
27
  case "tab_login_switch":
28
+ $this->mo2f_handle_login_enable($santizied_post);
29
  break;
30
  case "tab_backup_switch":
31
+ $this->mo2f_handle_backup_enable($santizied_post);
32
  break;
33
  case "tab_malware_switch":
34
+ $this->mo2f_handle_malware_enable($santizied_post);
35
  break;
36
  case "tab_block_switch":
37
+ $this->mo2f_handle_block_enable($santizied_post);
38
  break;
39
  case "tab_report_switch":
40
+ $this->mo2f_handle_report_enable($santizied_post);
41
  break;
42
  case "tab_notif_switch":
43
+ $this->mo2f_handle_notif_enable($santizied_post);
44
  break;
45
  }
46
  }
151
  else{
152
  update_site_option('mo_2f_switch_backup', 0);
153
  update_site_option('mo2f_tab_count', get_site_option('mo2f_tab_count')-1);
154
+ $handler_obj = new MoBackupSite;
155
  $handler_obj->bl_deactivate();
156
  update_site_option('mo2f_enable_cron_backup', 0);
157
  $handler_obj->file_backup_deactivate();
controllers/feedback_form.php CHANGED
@@ -1,18 +1,5 @@
1
  <?php
2
- global $moWpnsUtility, $dirName;
3
-
4
- //
5
- //if(current_user_can( 'manage_options' ) && isset($_POST['option']))
6
- //{
7
- // switch($_POST['option'])
8
- // {
9
- // case "mo_skip_feedback":
10
- // wpns_handle_skip_feedback($_POST); break;
11
- // case "mo_feedback":
12
- // wpns_handle_feedback($_POST); break;
13
- //
14
- // }
15
- //}
16
 
17
  function wpns_handle_skip_feedback($postdata){
18
  do_action('wpns_show_message',MoWpnsMessages::showMessage('FEEDBACK'),'CUSTOM_MESSAGE');
1
  <?php
2
+ global $moWpnsUtility, $mo2f_dirName;
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
  function wpns_handle_skip_feedback($postdata){
5
  do_action('wpns_show_message',MoWpnsMessages::showMessage('FEEDBACK'),'CUSTOM_MESSAGE');
controllers/ip-blocking.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
  $mo_wpns_handler = new MoWpnsHandler();
5
 
6
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
@@ -20,11 +20,13 @@
20
 
21
  $blockedips = $mo_wpns_handler->get_blocked_ips();
22
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
23
- $img_loader_url = plugins_url('wp-security-pro/includes/images/loader.gif');
 
 
 
24
  $page_url = "";
25
  $license_url = add_query_arg( array('page' => 'mo_2fa_upgrade'), $_SERVER['REQUEST_URI'] );
26
 
27
- //include $dirName . 'views/ip-blocking.php';
28
 
29
  /** IP BLOCKING RELATED FUNCTIONS **/
30
 
@@ -54,14 +56,12 @@
54
  if(!$isWhitelisted)
55
  {
56
  if($mo_wpns_config->is_ip_blocked($ipAddress)){
57
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('IP_ALREADY_BLOCKED'),'ERROR');
58
  //Change message
59
  echo("already blocked");
60
  exit;
61
  } else{
62
  $mo_wpns_config->block_ip($ipAddress, MoWpnsConstants::BLOCKED_BY_ADMIN, true);
63
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('IP_PERMANENTLY_BLOCKED'),'SUCCESS');
64
- //not in structures
65
  ?>
66
  <table id="blockedips_table1" class="display">
67
  <thead><tr><th>IP Address&emsp;&emsp;</th><th>Reason&emsp;&emsp;</th><th>Blocked Until&emsp;&emsp;</th><th>Blocked Date&emsp;&emsp;</th><th>Action&emsp;&emsp;</th></tr></thead>
@@ -70,7 +70,7 @@
70
  $mo_wpns_handler = new MoWpnsHandler();
71
  $blockedips = $mo_wpns_handler->get_blocked_ips();
72
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
73
- global $dirName;
74
  foreach($blockedips as $blockedip)
75
  {
76
  echo "<tr class='mo_wpns_not_bold'><td>".$blockedip->ip_address."</td><td>".$blockedip->reason."</td><td>";
@@ -94,7 +94,6 @@
94
  }
95
  else
96
  {
97
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('IP_IN_WHITELISTED'),'ERROR');
98
  // Change message
99
  echo("IP_IN_WHITELISTED");
100
  exit;
@@ -110,7 +109,6 @@
110
 
111
  if( $moWpnsUtility->check_empty_or_null($entryID))
112
  {
113
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('UNKNOWN_ERROR'),'ERROR');
114
  // Change message
115
  echo("UNKNOWN_ERROR");
116
  exit;
@@ -120,8 +118,7 @@
120
  $entryid = sanitize_text_field($entryID);
121
  $mo_wpns_config = new MoWpnsHandler();
122
  $mo_wpns_config->unblock_ip_entry($entryid);
123
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('IP_UNBLOCKED'),'SUCCESS');
124
- //not is structure
125
  ?>
126
  <table id="blockedips_table1" class="display">
127
  <thead><tr><th>IP Address&emsp;&emsp;</th><th>Reason&emsp;&emsp;</th><th>Blocked Until&emsp;&emsp;</th><th>Blocked Date&emsp;&emsp;</th><th>Action&emsp;&emsp;</th></tr></thead>
@@ -130,7 +127,7 @@
130
  $mo_wpns_handler = new MoWpnsHandler();
131
  $blockedips = $mo_wpns_handler->get_blocked_ips();
132
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
133
- global $dirName;
134
  foreach($blockedips as $blockedip)
135
  {
136
  echo "<tr class='mo_wpns_not_bold'><td>".$blockedip->ip_address."</td><td>".$blockedip->reason."</td><td>";
@@ -161,7 +158,6 @@
161
  global $moWpnsUtility;
162
  if( $moWpnsUtility->check_empty_or_null($ip))
163
  {
164
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('INVALID_IP'),'ERROR');
165
  //change message
166
  echo("EMPTY IP");
167
  exit;
@@ -177,7 +173,6 @@
177
  $mo_wpns_config = new MoWpnsHandler();
178
  if($mo_wpns_config->is_whitelisted($ipAddress))
179
  {
180
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('IP_ALREADY_WHITELISTED'),'ERROR');
181
  //change message
182
  echo("IP_ALREADY_WHITELISTED");
183
  exit;
@@ -185,7 +180,6 @@
185
  else
186
  {
187
  $mo_wpns_config->whitelist_ip($ip);
188
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('IP_WHITELISTED'),'SUCCESS');
189
  //Structures issues
190
  $mo_wpns_handler = new MoWpnsHandler();
191
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
@@ -223,7 +217,6 @@
223
  global $moWpnsUtility;
224
  if( $moWpnsUtility->check_empty_or_null($entryID))
225
  {
226
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('UNKNOWN_ERROR'),'ERROR');
227
  //change Message
228
  echo("UNKNOWN_ERROR");
229
  exit;
@@ -233,7 +226,6 @@
233
  $entryid = sanitize_text_field($entryID);
234
  $mo_wpns_config = new MoWpnsHandler();
235
  $mo_wpns_config->remove_whitelist_entry($entryid);
236
- //do_action('wpns_show_message',MoWpnsMessages::showMessage('IP_UNWHITELISTED'),'SUCCESS');
237
  //structures
238
  $mo_wpns_handler = new MoWpnsHandler();
239
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
  $mo_wpns_handler = new MoWpnsHandler();
5
 
6
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
20
 
21
  $blockedips = $mo_wpns_handler->get_blocked_ips();
22
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
23
+ $path = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.'loader.gif';
24
+ $path = explode('plugins', $path);
25
+ $img_loader_url = plugins_url().$path[1];
26
+
27
  $page_url = "";
28
  $license_url = add_query_arg( array('page' => 'mo_2fa_upgrade'), $_SERVER['REQUEST_URI'] );
29
 
 
30
 
31
  /** IP BLOCKING RELATED FUNCTIONS **/
32
 
56
  if(!$isWhitelisted)
57
  {
58
  if($mo_wpns_config->is_ip_blocked($ipAddress)){
 
59
  //Change message
60
  echo("already blocked");
61
  exit;
62
  } else{
63
  $mo_wpns_config->block_ip($ipAddress, MoWpnsConstants::BLOCKED_BY_ADMIN, true);
64
+ //not in structures
 
65
  ?>
66
  <table id="blockedips_table1" class="display">
67
  <thead><tr><th>IP Address&emsp;&emsp;</th><th>Reason&emsp;&emsp;</th><th>Blocked Until&emsp;&emsp;</th><th>Blocked Date&emsp;&emsp;</th><th>Action&emsp;&emsp;</th></tr></thead>
70
  $mo_wpns_handler = new MoWpnsHandler();
71
  $blockedips = $mo_wpns_handler->get_blocked_ips();
72
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
73
+ global $mo2f_dirName;
74
  foreach($blockedips as $blockedip)
75
  {
76
  echo "<tr class='mo_wpns_not_bold'><td>".$blockedip->ip_address."</td><td>".$blockedip->reason."</td><td>";
94
  }
95
  else
96
  {
 
97
  // Change message
98
  echo("IP_IN_WHITELISTED");
99
  exit;
109
 
110
  if( $moWpnsUtility->check_empty_or_null($entryID))
111
  {
 
112
  // Change message
113
  echo("UNKNOWN_ERROR");
114
  exit;
118
  $entryid = sanitize_text_field($entryID);
119
  $mo_wpns_config = new MoWpnsHandler();
120
  $mo_wpns_config->unblock_ip_entry($entryid);
121
+ //not is structure
 
122
  ?>
123
  <table id="blockedips_table1" class="display">
124
  <thead><tr><th>IP Address&emsp;&emsp;</th><th>Reason&emsp;&emsp;</th><th>Blocked Until&emsp;&emsp;</th><th>Blocked Date&emsp;&emsp;</th><th>Action&emsp;&emsp;</th></tr></thead>
127
  $mo_wpns_handler = new MoWpnsHandler();
128
  $blockedips = $mo_wpns_handler->get_blocked_ips();
129
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
130
+ global $mo2f_dirName;
131
  foreach($blockedips as $blockedip)
132
  {
133
  echo "<tr class='mo_wpns_not_bold'><td>".$blockedip->ip_address."</td><td>".$blockedip->reason."</td><td>";
158
  global $moWpnsUtility;
159
  if( $moWpnsUtility->check_empty_or_null($ip))
160
  {
 
161
  //change message
162
  echo("EMPTY IP");
163
  exit;
173
  $mo_wpns_config = new MoWpnsHandler();
174
  if($mo_wpns_config->is_whitelisted($ipAddress))
175
  {
 
176
  //change message
177
  echo("IP_ALREADY_WHITELISTED");
178
  exit;
180
  else
181
  {
182
  $mo_wpns_config->whitelist_ip($ip);
 
183
  //Structures issues
184
  $mo_wpns_handler = new MoWpnsHandler();
185
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
217
  global $moWpnsUtility;
218
  if( $moWpnsUtility->check_empty_or_null($entryID))
219
  {
 
220
  //change Message
221
  echo("UNKNOWN_ERROR");
222
  exit;
226
  $entryid = sanitize_text_field($entryID);
227
  $mo_wpns_config = new MoWpnsHandler();
228
  $mo_wpns_config->remove_whitelist_entry($entryid);
 
229
  //structures
230
  $mo_wpns_handler = new MoWpnsHandler();
231
  $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
controllers/licensing.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
  $default_url = add_query_arg( array('page' => 'default' ), $_SERVER['REQUEST_URI'] );
6
  $form_action = MoWpnsConstants::HOST_NAME.'/moas/login';
@@ -47,4 +47,4 @@
47
  'End to End Integration Support'
48
  );
49
 
50
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'licensing.php';
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
  $default_url = add_query_arg( array('page' => 'default' ), $_SERVER['REQUEST_URI'] );
6
  $form_action = MoWpnsConstants::HOST_NAME.'/moas/login';
47
  'End to End Integration Support'
48
  );
49
 
50
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'licensing.php';
controllers/login-security.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
  $twofactor_url = add_query_arg(
6
  array('page' => 'mo_2fa_two_fa')
@@ -43,19 +43,19 @@
43
  $time_of_blocking_val = get_option('mo2f_time_of_blocking_val') ? get_option('mo2f_time_of_blocking_val') : 3;
44
  $brute_force_enabled = get_option('mo2f_enable_brute_force') ? "checked" : "";
45
  $remaining_attempts = get_option('mo2f_show_remaining_attempts') ? "checked" : "";
46
- $slow_down_attacks = get_option('mo_wpns_slow_down_attacks') ? "checked" : "";
47
- $enable_2fa = get_option('mo_wpns_enable_2fa') ? "checked" : "";
48
 
49
  $enforce_strong_password= get_option('mo2f_enforce_strong_passswords') ? "checked" : "";
50
  $attack_delay = get_option('mo_wpns_slow_down_attacks_delay') ? get_option('mo_wpns_slow_down_attacks_delay'): 2 ;
51
  $google_recaptcha = get_option('mo_wpns_activate_recaptcha') ? "checked" : "";
52
- $test_recaptcha_url = "";
53
  $test_recaptcha_url = add_query_arg( array('option'=>'testrecaptchaconfig'), $_SERVER['REQUEST_URI'] );
54
- $captcha_url = 'https://www.google.com/recaptcha/admin#list';
55
- $captcha_site_key = get_option('mo_wpns_recaptcha_site_key');
56
- $captcha_secret_key = get_option('mo_wpns_recaptcha_secret_key');
57
- $captcha_login = get_option('mo_wpns_activate_recaptcha_for_login') ? "checked" : "";
58
- $captcha_reg = get_option('mo_wpns_activate_recaptcha_for_registration') ? "checked" : "";
59
 
60
 
61
  $strong_password_account= get_option('mo2f_enforce_strong_passswords_for_accounts') ? get_option('mo2f_enforce_strong_passswords_for_accounts') : "all";
@@ -85,7 +85,7 @@
85
 
86
 
87
 
88
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'login-security.php';
89
 
90
 
91
 
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
  $twofactor_url = add_query_arg(
6
  array('page' => 'mo_2fa_two_fa')
43
  $time_of_blocking_val = get_option('mo2f_time_of_blocking_val') ? get_option('mo2f_time_of_blocking_val') : 3;
44
  $brute_force_enabled = get_option('mo2f_enable_brute_force') ? "checked" : "";
45
  $remaining_attempts = get_option('mo2f_show_remaining_attempts') ? "checked" : "";
46
+ $slow_down_attacks = get_option('mo_wpns_slow_down_attacks') ? "checked" : "";
47
+ $enable_2fa = get_option('mo_wpns_enable_2fa') ? "checked" : "";
48
 
49
  $enforce_strong_password= get_option('mo2f_enforce_strong_passswords') ? "checked" : "";
50
  $attack_delay = get_option('mo_wpns_slow_down_attacks_delay') ? get_option('mo_wpns_slow_down_attacks_delay'): 2 ;
51
  $google_recaptcha = get_option('mo_wpns_activate_recaptcha') ? "checked" : "";
52
+ $test_recaptcha_url = "";
53
  $test_recaptcha_url = add_query_arg( array('option'=>'testrecaptchaconfig'), $_SERVER['REQUEST_URI'] );
54
+ $captcha_url = 'https://www.google.com/recaptcha/admin#list';
55
+ $captcha_site_key = get_option('mo_wpns_recaptcha_site_key');
56
+ $captcha_secret_key = get_option('mo_wpns_recaptcha_secret_key');
57
+ $captcha_login = get_option('mo_wpns_activate_recaptcha_for_login') ? "checked" : "";
58
+ $captcha_reg = get_option('mo_wpns_activate_recaptcha_for_registration') ? "checked" : "";
59
 
60
 
61
  $strong_password_account= get_option('mo2f_enforce_strong_passswords_for_accounts') ? get_option('mo2f_enforce_strong_passswords_for_accounts') : "all";
85
 
86
 
87
 
88
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'login-security.php';
89
 
90
 
91
 
controllers/login-spam.php CHANGED
@@ -1,11 +1,10 @@
1
  <?php
2
- global $moWpnsUtility,$dirName;
3
  if( isset( $_GET[ 'tab' ] ) ) {
4
  $active_tab = $_GET[ 'tab' ];
5
  } else {
6
  $active_tab = 'default';
7
  }
8
  update_site_option('mo2f_visit_login_and_spam',true);
9
-
10
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'login_spam.php';
11
  ?>
1
  <?php
2
+ global $moWpnsUtility,$mo2f_dirName;
3
  if( isset( $_GET[ 'tab' ] ) ) {
4
  $active_tab = $_GET[ 'tab' ];
5
  } else {
6
  $active_tab = 'default';
7
  }
8
  update_site_option('mo2f_visit_login_and_spam',true);
9
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'login_spam.php';
 
10
  ?>
controllers/main_controller.php CHANGED
@@ -1,30 +1,33 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
- $controller = $dirName . 'controllers'.DIRECTORY_SEPARATOR;
6
 
7
- include $controller . 'navbar.php';
8
- include $controller . 'newtork_security_features.php';
9
- if (!get_option('mo_wpns_2fa_with_network_security_popup_visible') && get_option('mo_wpns_2fa_with_network_security'))
10
- {
11
- include $controller . 'tour-model.php';
12
- }
 
 
 
13
 
14
  if( isset( $_GET[ 'page' ]))
15
  {
16
  switch($_GET['page'])
17
  {
18
  case 'mo_2fa_dashboard':
19
- include $controller . 'dashboard.php'; break;
20
- case 'mo_2fa_login_and_spam':
21
  include $controller . 'login-spam.php'; break;
22
  case 'default':
23
  include $controller . 'login-security.php'; break;
24
  case 'mo_2fa_account':
25
  include $controller . 'account.php'; break;
26
  case 'mo_2fa_backup':
27
- include $controller . 'backup.php'; break;
28
  case 'mo_2fa_upgrade':
29
  include $controller . 'upgrade.php'; break;
30
  case 'mo_2fa_waf':
@@ -42,35 +45,51 @@
42
  case 'mo_2fa_troubleshooting':
43
  include $controller . 'troubleshooting.php'; break;
44
  case 'mo_2fa_malwarescan':
45
- include $controller . 'malware_scanner'.DIRECTORY_SEPARATOR.'scan_malware.php'; break;
46
  case 'mo_2fa_two_fa':
47
- include $controller . 'twofa' . DIRECTORY_SEPARATOR . 'two_fa.php';
48
- update_option('mo2f_scan_nonce',wp_create_nonce('wpns-quick-scan')); break;
 
49
  }
50
  }
51
 
52
- include $controller . 'support.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  ?>
54
- <?php if(get_option('mo2f_scan_initialize')) { ?>
55
- <script>
56
- // jQuery(document).ready(function(){
57
- // var nonce = "<?php echo wp_create_nonce('wpns-quick-scan')?>";
58
- // var data={
59
- // 'action':'mo_wpns_malware_redirect',
60
- // 'call_type':'malware_scan_initiate',
61
- // 'scan':'scan_start',
62
- // 'scantype':'quick_scan',
63
- // 'nonce': nonce
64
- // };
65
- // jQuery.post(ajaxurl, data, function(response){
66
- // jQuery('input[name="quick_scan_button"]').removeAttr('disabled');
67
- // document.getElementById('quick_scan_button').style.backgroundColor = '#20b2aa';
68
- // jQuery('input[name="standard_scan_button"]').removeAttr('disabled');
69
- // document.getElementById('standard_scan_button').style.backgroundColor = '#20b2aa';
70
- // jQuery('input[name="custom_scan_button"]').removeAttr('disabled');
71
- // document.getElementById('custom_scan_button').style.backgroundColor = '#20b2aa';
72
- // document.getElementById("quick_scan_button").value = "Quick Scan";
73
- // });
74
- // });
75
- </script>
76
- <?php } ?>
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
+ $controller = $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR;
6
 
7
+
8
+ if(current_user_can('administrator'))
9
+ {
10
+ include $controller . 'navbar.php';
11
+ include $controller . 'newtork_security_features.php';
12
+ if (!get_option('mo_wpns_2fa_with_network_security_popup_visible') && get_option('mo_wpns_2fa_with_network_security'))
13
+ {
14
+ include $controller . 'tour-model.php';
15
+ }
16
 
17
  if( isset( $_GET[ 'page' ]))
18
  {
19
  switch($_GET['page'])
20
  {
21
  case 'mo_2fa_dashboard':
22
+ include $controller . 'dashboard.php'; break;
23
+ case 'mo_2fa_login_and_spam':
24
  include $controller . 'login-spam.php'; break;
25
  case 'default':
26
  include $controller . 'login-security.php'; break;
27
  case 'mo_2fa_account':
28
  include $controller . 'account.php'; break;
29
  case 'mo_2fa_backup':
30
+ include $controller . 'backup'.DIRECTORY_SEPARATOR.'backup.php'; break;
31
  case 'mo_2fa_upgrade':
32
  include $controller . 'upgrade.php'; break;
33
  case 'mo_2fa_waf':
45
  case 'mo_2fa_troubleshooting':
46
  include $controller . 'troubleshooting.php'; break;
47
  case 'mo_2fa_malwarescan':
48
+ include $controller . 'malware_scanner'.DIRECTORY_SEPARATOR.'scan_malware.php'; break;
49
  case 'mo_2fa_two_fa':
50
+ include $controller .'twofa'.DIRECTORY_SEPARATOR. 'two_fa.php'; break;
51
+ case 'mo_2fa_request_demo':
52
+ include $controller . 'request_demo.php';
53
  }
54
  }
55
 
56
+ include $controller . 'support.php';
57
+ }
58
+ else
59
+ {
60
+ if( isset( $_GET[ 'page' ]))
61
+ {
62
+ switch($_GET['page'])
63
+ {
64
+ case 'mo_2fa_two_fa':
65
+ include $controller .'twofa'.DIRECTORY_SEPARATOR. 'two_fa.php'; break;
66
+
67
+ }
68
+
69
+ }
70
+
71
+ }
72
  ?>
73
+ <?php //if(get_option('mo_wpns_scan_initialize')) { ?>
74
+ <!-- <script>
75
+ jQuery(document).ready(function(){
76
+ var nonce = "<?php //echo wp_create_nonce('wpns-quick-scan');?>";
77
+ var data={
78
+ 'action':'mo_wpns_malware_redirect',
79
+ 'call_type':'malware_scan_initiate',
80
+ 'scan':'scan_start',
81
+ 'scantype':'quick_scan',
82
+ 'nonce': nonce
83
+ };
84
+ jQuery.post(ajaxurl, data, function(response){
85
+ jQuery('input[name="quick_scan_button"]').removeAttr('disabled');
86
+ document.getElementById('quick_scan_button').style.backgroundColor = '#20b2aa';
87
+ jQuery('input[name="standard_scan_button"]').removeAttr('disabled');
88
+ document.getElementById('standard_scan_button').style.backgroundColor = '#20b2aa';
89
+ jQuery('input[name="custom_scan_button"]').removeAttr('disabled');
90
+ document.getElementById('custom_scan_button').style.backgroundColor = '#20b2aa';
91
+ document.getElementById("quick_scan_button").value = "Quick Scan";
92
+ });
93
+ });
94
+ </script> -->
95
+ <?php //} ?>
controllers/malware_scanner/malware_scan_ajax.php CHANGED
@@ -49,8 +49,6 @@ class Mo_wpns_scan_malware
49
  wp_send_json('level_error');
50
  }
51
  else{
52
-
53
-
54
  $mo_wpns_scan_plugins=isset($POSTED['scan_plugin']) ? sanitize_text_field($POSTED['scan_plugin']) : 0;
55
  $mo_wpns_scan_themes=isset($POSTED['scan_themes']) ? sanitize_text_field($POSTED['scan_themes']) : 0;
56
  $mo_wpns_scan_wp_files= isset($POSTED['scan_core']) ? sanitize_text_field($POSTED['scan_core']) : 0;
@@ -79,10 +77,8 @@ class Mo_wpns_scan_malware
79
  wp_send_json('path_error');
80
  }
81
  }
82
-
83
  $mo_wpns_skip_folders=$str;
84
  }else{
85
-
86
  $mo_wpns_skip_folders=$folders_to_skip;
87
  }
88
 
@@ -116,7 +112,7 @@ class Mo_wpns_scan_malware
116
  if($status == "IN PROGRESS"){
117
  wp_send_json('scanning_already');
118
  }
119
- global $moWpnsUtility, $dirName;
120
 
121
  $mo_wpns_scan_handler = new Mo_wpns_Scan_Handler_Cron();
122
  $mo2f_malware_db_handler = new MoWpnsDB();
@@ -270,7 +266,7 @@ class Mo_wpns_scan_malware
270
 
271
 
272
  public function mo_wpns_get_progress(){
273
-
274
  $decoded_scan_status=json_decode(get_option('mo_wpns_scan_status'));
275
  $status= $decoded_scan_status->scan_progress;;
276
  $files_scanned= $decoded_scan_status->files_scanned;
@@ -285,7 +281,6 @@ class Mo_wpns_scan_malware
285
  $time_spent_in_downloading= time()-$status_download;
286
 
287
  if($time_spent_in_downloading > 600){
288
-
289
  $mo2f_malware_db_handler = new MoWpnsDB();
290
  $reportid= get_option('mo2f_report_id');
291
  $last_report = $mo2f_malware_db_handler->get_report_with_id($reportid);
@@ -345,7 +340,6 @@ class Mo_wpns_scan_malware
345
  }
346
 
347
  function mo_wpns_stop_scan(){
348
- error_log("Stop Scan");
349
  update_option('mo_stop_scan','1');
350
  $mo2f_malware_db_handler = new MoWpnsDB();
351
  $mo2f_malware_db_handler->delete_files_parts();
49
  wp_send_json('level_error');
50
  }
51
  else{
 
 
52
  $mo_wpns_scan_plugins=isset($POSTED['scan_plugin']) ? sanitize_text_field($POSTED['scan_plugin']) : 0;
53
  $mo_wpns_scan_themes=isset($POSTED['scan_themes']) ? sanitize_text_field($POSTED['scan_themes']) : 0;
54
  $mo_wpns_scan_wp_files= isset($POSTED['scan_core']) ? sanitize_text_field($POSTED['scan_core']) : 0;
77
  wp_send_json('path_error');
78
  }
79
  }
 
80
  $mo_wpns_skip_folders=$str;
81
  }else{
 
82
  $mo_wpns_skip_folders=$folders_to_skip;
83
  }
84
 
112
  if($status == "IN PROGRESS"){
113
  wp_send_json('scanning_already');
114
  }
115
+ global $moWpnsUtility, $mo2f_dirName;
116
 
117
  $mo_wpns_scan_handler = new Mo_wpns_Scan_Handler_Cron();
118
  $mo2f_malware_db_handler = new MoWpnsDB();
266
 
267
 
268
  public function mo_wpns_get_progress(){
269
+
270
  $decoded_scan_status=json_decode(get_option('mo_wpns_scan_status'));
271
  $status= $decoded_scan_status->scan_progress;;
272
  $files_scanned= $decoded_scan_status->files_scanned;
281
  $time_spent_in_downloading= time()-$status_download;
282
 
283
  if($time_spent_in_downloading > 600){
 
284
  $mo2f_malware_db_handler = new MoWpnsDB();
285
  $reportid= get_option('mo2f_report_id');
286
  $last_report = $mo2f_malware_db_handler->get_report_with_id($reportid);
340
  }
341
 
342
  function mo_wpns_stop_scan(){
 
343
  update_option('mo_stop_scan','1');
344
  $mo2f_malware_db_handler = new MoWpnsDB();
345
  $mo2f_malware_db_handler->delete_files_parts();
controllers/malware_scanner/scan_malware.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
  add_option('mo_wpns_skip_folders');
6
  update_site_option('mo2f_visit_malware',true);
7
 
8
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'malware_scan.php';
9
  ?>
10
 
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
  add_option('mo_wpns_skip_folders');
6
  update_site_option('mo2f_visit_malware',true);
7
 
8
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'malware_scan.php';
9
  ?>
10
 
controllers/malware_scanner/scan_malware_report.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
 
3
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_report_view.php';
4
 
5
  ?>
1
  <?php
2
 
3
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_report_view.php';
4
 
5
  ?>
controllers/malware_scanner/scan_malware_settings.php CHANGED
@@ -45,5 +45,5 @@ $mo_wpns_custom_sign_array = array();
45
  if(!empty($mo_wpns_custom_sign)){
46
  $mo_wpns_custom_sign_array = explode(";",$mo_wpns_custom_sign);
47
  }
48
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_settings_view.php';
49
- ?>
45
  if(!empty($mo_wpns_custom_sign)){
46
  $mo_wpns_custom_sign_array = explode(";",$mo_wpns_custom_sign);
47
  }
48
+ include_once $mo2f_dirName. 'views'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_settings_view.php';
49
+ ?>
controllers/malware_scanner/scan_malware_summary.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
 
3
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_summary_view.php';
4
 
5
  ?>
1
  <?php
2
 
3
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_summary_view.php';
4
 
5
  ?>
controllers/navbar.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
5
  {
6
  switch(sanitize_text_field(wp_unslash($_POST['option'])))
@@ -8,12 +8,9 @@
8
  case "mo_wpns_2fa_with_network_security":
9
  $security_features = new Mo_2fa_security_features();
10
  $security_features->wpns_2fa_with_network_security($_POST); break;
11
-
12
  }
13
  }
14
  $network_security_features= get_option('mo_wpns_2fa_with_network_security') ? "checked" : "";
15
-
16
-
17
 
18
  if( isset( $_GET[ 'page' ])){
19
  $tab_count= get_site_option('mo2f_tab_count', 0);
@@ -78,13 +75,14 @@
78
  //Added for new design
79
  $dashboard_url = add_query_arg(array('page' => 'mo_2fa_dashboard' ), $_SERVER['REQUEST_URI']);
80
  $upgrade_url = add_query_arg(array('page' => 'mo_2fa_upgrade' ), $_SERVER['REQUEST_URI']);
 
81
  //dynamic
82
  $logo_url = plugin_dir_url(dirname(__FILE__)) . 'includes/images/miniorange_logo.png';
83
- // $logo_url = plugin_dir_url($dirName) . 'wp-security-pro/includes/images/miniorange_logo.png';
84
  $shw_feedback = get_option('donot_show_feedback_message') ? false: true;
 
85
  $moPluginHandler= new MoWpnsHandler();
86
  $safe = $moPluginHandler->is_whitelisted($moWpnsUtility->get_client_ip());
87
 
88
  $active_tab = $_GET['page'];
89
 
90
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'navbar.php';
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
5
  {
6
  switch(sanitize_text_field(wp_unslash($_POST['option'])))
8
  case "mo_wpns_2fa_with_network_security":
9
  $security_features = new Mo_2fa_security_features();
10
  $security_features->wpns_2fa_with_network_security($_POST); break;
 
11
  }
12
  }
13
  $network_security_features= get_option('mo_wpns_2fa_with_network_security') ? "checked" : "";
 
 
14
 
15
  if( isset( $_GET[ 'page' ])){
16
  $tab_count= get_site_option('mo2f_tab_count', 0);
75
  //Added for new design
76
  $dashboard_url = add_query_arg(array('page' => 'mo_2fa_dashboard' ), $_SERVER['REQUEST_URI']);
77
  $upgrade_url = add_query_arg(array('page' => 'mo_2fa_upgrade' ), $_SERVER['REQUEST_URI']);
78
+ $request_demo_url = add_query_arg(array('page' => 'mo_2fa_request_demo' ), $_SERVER['REQUEST_URI']);
79
  //dynamic
80
  $logo_url = plugin_dir_url(dirname(__FILE__)) . 'includes/images/miniorange_logo.png';
 
81
  $shw_feedback = get_option('donot_show_feedback_message') ? false: true;
82
+
83
  $moPluginHandler= new MoWpnsHandler();
84
  $safe = $moPluginHandler->is_whitelisted($moWpnsUtility->get_client_ip());
85
 
86
  $active_tab = $_GET['page'];
87
 
88
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'navbar.php';
controllers/newtork_security_features.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $dirName;
4
  if(current_user_can( 'manage_options' ) && isset($_POST['mo_wpns_features']))
5
  {
6
  switch(sanitize_text_field(wp_unslash($_POST['mo_wpns_features'])))
@@ -21,4 +21,4 @@
21
 
22
 
23
 
24
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'network_security_features.php';
1
  <?php
2
 
3
+ global $mo2f_dirName;
4
  if(current_user_can( 'manage_options' ) && isset($_POST['mo_wpns_features']))
5
  {
6
  switch(sanitize_text_field(wp_unslash($_POST['mo_wpns_features'])))
21
 
22
 
23
 
24
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'network_security_features.php';
controllers/notification-settings.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
  $template1 = "Hello,<br><br>The user with IP Address <b>##ipaddress##</b> has exceeded allowed trasaction limit on your website <b>".get_bloginfo()."</b> and we have blocked his IP address for further access to website.<br><br>You can login to your WordPress dashaboard to check more details.<br><br>Thanks,<br>miniOrange";
6
  $template2 = "Hello ##username##,<br><br>Your account was logged in from new IP Address <b>##ipaddress##</b> on website <b>".get_bloginfo()."</b>. Please <a href='mailto:".MoWpnsConstants::SUPPORT_EMAIL."'>contact us</a> if you don't recognise this activity.<br><br>Thanks,<br>".get_bloginfo();
@@ -41,7 +41,7 @@
41
  'textarea_name' => 'custom_user_template',
42
  'wpautop' => false
43
  );
44
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'notification-settings.php';
45
 
46
 
47
 
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
  $template1 = "Hello,<br><br>The user with IP Address <b>##ipaddress##</b> has exceeded allowed trasaction limit on your website <b>".get_bloginfo()."</b> and we have blocked his IP address for further access to website.<br><br>You can login to your WordPress dashaboard to check more details.<br><br>Thanks,<br>miniOrange";
6
  $template2 = "Hello ##username##,<br><br>Your account was logged in from new IP Address <b>##ipaddress##</b> on website <b>".get_bloginfo()."</b>. Please <a href='mailto:".MoWpnsConstants::SUPPORT_EMAIL."'>contact us</a> if you don't recognise this activity.<br><br>Thanks,<br>".get_bloginfo();
41
  'textarea_name' => 'custom_user_template',
42
  'wpautop' => false
43
  );
44
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'notification-settings.php';
45
 
46
 
47
 
controllers/registration-security.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility, $dirName;
4
 
5
 
6
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
@@ -17,7 +17,7 @@
17
  }
18
  }
19
 
20
- $otpVerify_url = add_query_arg( array('page' => 'mo_customer_validation_settings', 'tab'=>'settings'), $_SERVER['REQUEST_URI'] );
21
  $openid_url = add_query_arg( array('page' => 'mo_openid_settings' ), $_SERVER['REQUEST_URI'] );
22
  $domain_blocking= get_option('mo_wpns_enable_fake_domain_blocking') ? "checked" : "";
23
  $user_verify = get_option('mo_wpns_enable_advanced_user_verification') ? "checked" : "";
@@ -77,7 +77,7 @@
77
  }
78
  }
79
 
80
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'registration-security.php';
81
 
82
 
83
 
1
  <?php
2
 
3
+ global $moWpnsUtility, $mo2f_dirName;
4
 
5
 
6
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
17
  }
18
  }
19
 
20
+ $otpVerify_url = add_query_arg( array('page' => 'mosettings', 'tab'=>'settings'), $_SERVER['REQUEST_URI'] );
21
  $openid_url = add_query_arg( array('page' => 'mo_openid_settings' ), $_SERVER['REQUEST_URI'] );
22
  $domain_blocking= get_option('mo_wpns_enable_fake_domain_blocking') ? "checked" : "";
23
  $user_verify = get_option('mo_wpns_enable_advanced_user_verification') ? "checked" : "";
77
  }
78
  }
79
 
80
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'registration-security.php';
81
 
82
 
83
 
controllers/reports.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
  if(isset($_POST['option']) and $_POST['option']=='mo_wpns_manual_clear'){
6
  global $wpdb;
@@ -20,7 +20,7 @@
20
  $logintranscations = $mo_wpns_handler->get_login_transaction_report();
21
  $errortranscations = $mo_wpns_handler->get_error_transaction_report();
22
 
23
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'reports.php';
24
 
25
  ?>
26
 
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
  if(isset($_POST['option']) and $_POST['option']=='mo_wpns_manual_clear'){
6
  global $wpdb;
20
  $logintranscations = $mo_wpns_handler->get_login_transaction_report();
21
  $errortranscations = $mo_wpns_handler->get_error_transaction_report();
22
 
23
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'reports.php';
24
 
25
  ?>
26
 
controllers/request_demo.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ if(current_user_can( 'manage_options' ) && isset($_POST['option']) )
5
+ {
6
+ switch($_POST['option'])
7
+ {
8
+ case "mo_2FA_demo_request_form":
9
+ wpns_handle_demo_request_form($_POST); break;
10
+ }
11
+ }
12
+
13
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'request_demo.php';
14
+
15
+ function wpns_handle_demo_request_form($post){
16
+ $nonce = isset($post['nonce'])?$post['nonce']:NULL;
17
+ $usecase = isset($post['mo_2FA_demo_usecase'])? $post['mo_2FA_demo_usecase']: NULL;
18
+ $email = isset($post['mo_2FA_demo_email'])? $post['mo_2FA_demo_email'] : NULL;
19
+ $demo_plan = isset($post['mo_2FA_demo_plan'])? $post['mo_2FA_demo_plan']: NULL;
20
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-Request-demo' ) ){
21
+ return;
22
+ }
23
+ if(empty($usecase) || empty($email) || empty($demo_plan) )
24
+ {
25
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('DEMO_FORM_ERROR'),'SUCCESS');
26
+ return;
27
+ }
28
+ else{
29
+
30
+ $usecase = sanitize_text_field( $usecase );
31
+ $email = sanitize_text_field( $email );
32
+ $demo_plan = sanitize_text_field($demo_plan);
33
+ $query = 'REQUEST FOR DEMO';
34
+ $query .= ' =>';
35
+ $query .= $demo_plan;
36
+ $query .= ' : ';
37
+ $query .= $usecase;
38
+ $contact_us = new MocURL();
39
+ $submited = json_decode($contact_us->submit_contact_us($email, '', $query),true);
40
+
41
+ if(json_last_error() == JSON_ERROR_NONE && $submited)
42
+ {
43
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('SUPPORT_FORM_SENT'),'SUCCESS');
44
+ return;
45
+ }
46
+ else{
47
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('SUPPORT_FORM_ERROR'),'ERROR');
48
+ }
49
+ }
50
+ }
51
+ ?>
controllers/support.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $dirName;
4
 
5
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
6
  {
@@ -19,7 +19,7 @@
19
  if(empty($email))
20
  $email = $current_user->user_email;
21
 
22
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'support.php';
23
 
24
 
25
  /* SUPPORT FORM RELATED FUNCTIONS */
1
  <?php
2
 
3
+ global $mo2f_dirName;
4
 
5
  if(current_user_can( 'manage_options' ) && isset($_POST['option']))
6
  {
19
  if(empty($email))
20
  $email = $current_user->user_email;
21
 
22
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'support.php';
23
 
24
 
25
  /* SUPPORT FORM RELATED FUNCTIONS */
controllers/tour-model.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- global $dirName;
4
  $current_user = wp_get_current_user();
5
  $email = get_option("mo2f_email");
6
  $phone = get_option("mo_wpns_admin_phone");
@@ -15,8 +15,6 @@
15
  <p id="body-para-instr" class="modal-body-para" style="font-size: large;text-align: center;font-weight: 700;color: black;">Please select type of site to take a quick tour of setting up the plugin</p>
16
  <div style="text-align: center; padding-bottom: 10px;"><span id="span-ecommerce" onclick="change_span_css(this);" class="modal-span">Ecommerce</span><span id="span-business" onclick="change_span_css(this);" class="modal-span">Business</span><span id="span-blog" onclick="change_span_css(this);" class="modal-span">Blogs/News</span><span id="span-other" onclick="change_span_css(this);" class="modal-span">Other</span></div>';
17
 
18
- // $waf_data = array('ecommerce' => , 'business'=> , 'blog'=> , 'other'=> );
19
- // $waf_data = array('ecommerce' => 'It includes sensitive data such as user details, credit/debit card details.', 'business'=> '', 'blog'=> 'It includes users data, post data.', 'other'=> '');
20
 
21
  $waf_arr_ecc = '<div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-1" style="width: 98%; overflow: ; height: ;line-height: 1.5;"><b><u>Data theft and manipulation</u>:</b> Data manipulation can lead to alter, delete, destroy data. The manipulated data may or may not be regained. It includes very sensitive data such as user details, credit/debit card or bank details. It is very necessary to fix the existing data vulnerability issues, data leaks, change weak passwords and provide high end security to stop data breach and manipulation.<div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent SQL-Injection attacks:</span> SQL-Injection is web security vulnerability through SQL queries executed to modify, delete and destroy data. </div></div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-1" onclick="open_hide(this);">-</a></div></div><div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-2" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>Web Scraping</u>:</b> Web scraping is a used to extract large amount of data from websites and saved on local computer. The web scraping involves fetching and extracting data from it. It can be used to web indexing, web mining, data mining, research, tracking online presence and reputation, etc. Media scraping, price scraping are also some scraping techniques which are used to degrade/destroy media files and change the price of products.<div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent Cross-site scripting(XSS) attacks:</span> Cross site scripts used to web scraping and data extraction.</div></div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-2" onclick="open_hide(this);">+</a></div></div><div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-3" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>File manipualtion</u>:</b> The file manipuaiton used to alter, delete, execution of files on the sever. It leads to spoil site, spread malicious content which will harm to the business. <div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent Remote File Inclusion attacks:</span> Remote file inclusion used to include local file into the server. RFI is type of vulnerability which can lead to add malicious file through a script on server.</div><div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent Local File Inclusion attacks:</span> Local file inclusion used to access local file available on the server. LFI can be achieved by uploading malicious file to the server.</div></div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-3" onclick="open_hide(this);">+</a></div></div><div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-4" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>Content modification</u>:</b> Cross-site scripting used to change or modify data shown on website. Content modification affects a lot on business due to irrelevent content, malicious links which leads to spoil the trust of clients and reputation of organizations.<div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent SQL-Injection attacks:</span> SQL-Injection attack can change data in database. The data used to view content such as statistical data, charts, graphs, etc. It may mislead to business.</div><div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent Cross-site scripting(XSS) attacks:</span> Cross site script can add malicious links, change content of site. </div></div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-4" onclick="open_hide(this);">+</a></div></div>';
22
 
@@ -43,15 +41,6 @@
43
  <div style="width:50%;font-size: medium;">4: <b>Content modification</b></div></div>
44
  </div>';
45
 
46
- // foreach ($waf_arr as $key => $value) {
47
- // $waf_body.= '<div class="modal-body-div-c modal-body-div-d">';
48
- // if($counter==0)
49
- // $waf_body.= '<div id="div-show-hide-'.$counter.'" style="width: 98%; overflow:; height: ;line-height: 1.5;"><b><u>'.$key.'</u></b> '.$value.'</div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-'.$counter.'" onclick="open_hide(this);">-</a></div></div>';
50
- // else
51
- // $waf_body.= '<div id="div-show-hide-'.$counter.'" style="width: 98%; overflow:hidden; height: 50px;line-height: 1.5;"><b><u>'.$key.'</u></b> '.$value.'</div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-'.$counter.'" onclick="open_hide(this);">+</a></div></div>';
52
- // $counter+=$counter+1;
53
- // }
54
-
55
  $registration_security_ecommerce = '<div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-13" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>Registratoin security:</u></b> Ecommerce sites need to prevent fake registrations. It helps to keep site safe from suspicious user.';
56
  $registration_security_business = '<div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-13" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>Registratoin security:</u></b> Business sites need to prevent fake registrations. It helps to keep site safe from suspicious user.';
57
 
@@ -267,4 +256,4 @@
267
 
268
  $main_pointer = array('Main' => array('Let\'s get Started', $tour_body), 'Ecommerce' => $ecommerce_site, 'Business' => $business_site, 'Blogs/News' => $blog_site, 'Other' => $other_site);
269
 
270
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'tour-model.php';
1
  <?php
2
 
3
+ global $mo2f_dirName;
4
  $current_user = wp_get_current_user();
5
  $email = get_option("mo2f_email");
6
  $phone = get_option("mo_wpns_admin_phone");
15
  <p id="body-para-instr" class="modal-body-para" style="font-size: large;text-align: center;font-weight: 700;color: black;">Please select type of site to take a quick tour of setting up the plugin</p>
16
  <div style="text-align: center; padding-bottom: 10px;"><span id="span-ecommerce" onclick="change_span_css(this);" class="modal-span">Ecommerce</span><span id="span-business" onclick="change_span_css(this);" class="modal-span">Business</span><span id="span-blog" onclick="change_span_css(this);" class="modal-span">Blogs/News</span><span id="span-other" onclick="change_span_css(this);" class="modal-span">Other</span></div>';
17
 
 
 
18
 
19
  $waf_arr_ecc = '<div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-1" style="width: 98%; overflow: ; height: ;line-height: 1.5;"><b><u>Data theft and manipulation</u>:</b> Data manipulation can lead to alter, delete, destroy data. The manipulated data may or may not be regained. It includes very sensitive data such as user details, credit/debit card or bank details. It is very necessary to fix the existing data vulnerability issues, data leaks, change weak passwords and provide high end security to stop data breach and manipulation.<div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent SQL-Injection attacks:</span> SQL-Injection is web security vulnerability through SQL queries executed to modify, delete and destroy data. </div></div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-1" onclick="open_hide(this);">-</a></div></div><div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-2" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>Web Scraping</u>:</b> Web scraping is a used to extract large amount of data from websites and saved on local computer. The web scraping involves fetching and extracting data from it. It can be used to web indexing, web mining, data mining, research, tracking online presence and reputation, etc. Media scraping, price scraping are also some scraping techniques which are used to degrade/destroy media files and change the price of products.<div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent Cross-site scripting(XSS) attacks:</span> Cross site scripts used to web scraping and data extraction.</div></div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-2" onclick="open_hide(this);">+</a></div></div><div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-3" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>File manipualtion</u>:</b> The file manipuaiton used to alter, delete, execution of files on the sever. It leads to spoil site, spread malicious content which will harm to the business. <div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent Remote File Inclusion attacks:</span> Remote file inclusion used to include local file into the server. RFI is type of vulnerability which can lead to add malicious file through a script on server.</div><div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent Local File Inclusion attacks:</span> Local file inclusion used to access local file available on the server. LFI can be achieved by uploading malicious file to the server.</div></div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-3" onclick="open_hide(this);">+</a></div></div><div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-4" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>Content modification</u>:</b> Cross-site scripting used to change or modify data shown on website. Content modification affects a lot on business due to irrelevent content, malicious links which leads to spoil the trust of clients and reputation of organizations.<div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent SQL-Injection attacks:</span> SQL-Injection attack can change data in database. The data used to view content such as statistical data, charts, graphs, etc. It may mislead to business.</div><div class="modal-waf-dinner"><span class="modal-waf-sinner">Prevent Cross-site scripting(XSS) attacks:</span> Cross site script can add malicious links, change content of site. </div></div><div style="width: 2%; font-size: xx-large;"><a id="show-hide-4" onclick="open_hide(this);">+</a></div></div>';
20
 
41
  <div style="width:50%;font-size: medium;">4: <b>Content modification</b></div></div>
42
  </div>';
43
 
 
 
 
 
 
 
 
 
 
44
  $registration_security_ecommerce = '<div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-13" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>Registratoin security:</u></b> Ecommerce sites need to prevent fake registrations. It helps to keep site safe from suspicious user.';
45
  $registration_security_business = '<div class="modal-body-div-c modal-body-div-d"><div id="div-show-hide-13" style="width: 98%; overflow: hidden; height: 50px;line-height: 1.5;"><b><u>Registratoin security:</u></b> Business sites need to prevent fake registrations. It helps to keep site safe from suspicious user.';
46
 
256
 
257
  $main_pointer = array('Main' => array('Let\'s get Started', $tour_body), 'Ecommerce' => $ecommerce_site, 'Business' => $business_site, 'Blogs/News' => $blog_site, 'Other' => $other_site);
258
 
259
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'tour-model.php';
controllers/troubleshooting.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
 
3
- global $moWpnsUtility,$dirName;
4
 
5
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'troubleshooting.php';
1
  <?php
2
 
3
+ global $moWpnsUtility,$mo2f_dirName;
4
 
5
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'troubleshooting.php';
controllers/twofa/mo2fa_common_login.php CHANGED
@@ -248,7 +248,8 @@ function mo2f_get_forgotphone_form( $login_status, $login_message, $redirect_to,
248
  <?php }
249
 
250
  function mo2f_get_kba_authentication_prompt( $login_message, $redirect_to, $session_id_encrypt , $cookievalue) {
251
- $mo2f_login_option = get_option( 'mo2f_login_option' );
 
252
  $mo2f_remember_device_enabled = get_option( 'mo2f_remember_device' );
253
  ?>
254
  <html>
@@ -346,11 +347,14 @@ function mo2f_get_kba_authentication_prompt( $login_message, $redirect_to, $sess
346
  }
347
 
348
  function mo2f_get_push_notification_oobemail_prompt( $id, $login_status, $login_message, $redirect_to, $session_id_encrypt, $cookievalue ) {
349
- global $Mo2fdbQueries;
350
  $mo2f_enable_forgotphone = get_option( 'mo2f_enable_forgotphone' );
351
  $mo2f_KBA_config_status = $Mo2fdbQueries->get_user_detail( 'mo2f_SecurityQuestions_config_status', $id );
352
  $mo2f_is_new_customer = get_option( 'mo2f_is_NC' );
353
- ?>
 
 
 
354
  <html>
355
  <head>
356
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -429,12 +433,16 @@ function mo2f_get_push_notification_oobemail_prompt( $id, $login_status, $login_
429
  <input type="hidden" name="miniorange_mobile_validation_failed_nonce"
430
  value="<?php echo wp_create_nonce( 'miniorange-2-factor-mobile-validation-failed-nonce' ); ?>"/>
431
  <input type="hidden" name="session_id" value="<?php echo $session_id_encrypt; ?>"/>
 
 
432
  </form>
433
  <form name="f" id="mo2f_mobile_validation_form" method="post" class="mo2f_display_none_forms">
434
  <input type="hidden" name="miniorange_mobile_validation_nonce"
435
  value="<?php echo wp_create_nonce( 'miniorange-2-factor-mobile-validation-nonce' ); ?>"/>
436
  <input type="hidden" name="redirect_to" value="<?php echo $redirect_to; ?>"/>
437
  <input type="hidden" name="session_id" value="<?php echo $session_id_encrypt; ?>"/>
 
 
438
  </form>
439
  <form name="f" id="mo2f_show_softtoken_loginform" method="post" class="mo2f_display_none_forms">
440
  <input type="hidden" name="miniorange_softtoken"
@@ -455,10 +463,46 @@ function mo2f_get_push_notification_oobemail_prompt( $id, $login_status, $login_
455
  <input type="hidden" name="redirect_to" value="<?php echo $redirect_to; ?>"/>
456
  <input type="hidden" name="session_id" value="<?php echo $session_id_encrypt; ?>"/>
457
  </form>
458
-
459
  <script>
460
  var timeout;
 
 
461
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
462
  pollPushValidation();
463
  function pollPushValidation() {
464
  var transId = "<?php echo $cookievalue;// echo MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_transactionId',$session_id_encrypt ); ?>";
@@ -483,7 +527,7 @@ function mo2f_get_push_notification_oobemail_prompt( $id, $login_status, $login_
483
  }
484
  });
485
  }
486
-
487
 
488
  function mologinoffline() {
489
  jQuery('#mo2f_show_softtoken_loginform').submit();
@@ -654,9 +698,8 @@ function mo2f_get_qrcode_authentication_prompt( $login_status, $login_message, $
654
  function mo2f_get_otp_authentication_prompt( $login_status, $login_message, $redirect_to,$session_id_encrypt,$user_id ) {
655
  $mo2f_enable_forgotphone = get_option( 'mo2f_enable_forgotphone' );
656
  $mo2f_is_new_customer = get_option( 'mo2f_is_NC' );
657
- //update_user_meta( $currentuser->ID, 'mo2f_user_login_attempts', get_option('mo2f_allwed_login_attempts') );
658
- $attempts=get_user_meta( $user_id, 'mo2f_user_login_attempts', true );
659
- ?>
660
  <html>
661
  <head>
662
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
@@ -684,14 +727,13 @@ function mo2f_get_otp_authentication_prompt( $login_status, $login_message, $red
684
  <p class="mo2fa_display_message_frontend"><?php echo $login_message; ?></p>
685
  </div>
686
  <?php } ?><br><?php
687
- if(get_option( 'mo2f_enable_brute_force' )){?>
688
  <span><b>Attempts left</b>:</span> <?php echo $attempts;?><br>
689
  <?php if($attempts==1){?>
690
  <span style='color:red;'><b>If you fail to verify your identity, you will be redirected back to login page to verify your credentials.</b></span> <br>
691
  <?php }?>
692
  <br>
693
- <?php }?>
694
- <div id="showOTP">
695
  <div class="mo2f-login-container">
696
  <form name="f" id="mo2f_submitotp_loginform" method="post">
697
  <center>
@@ -711,8 +753,10 @@ function mo2f_get_otp_authentication_prompt( $login_status, $login_message, $red
711
  <input type="hidden" name="redirect_to" value="<?php echo $redirect_to; ?>"/>
712
  <input type="hidden" name="session_id" value="<?php echo $session_id_encrypt; ?>"/>
713
  </form>
714
- <?php if ( ! $mo2f_is_new_customer ) { ?>
715
- <?php if ( $mo2f_enable_forgotphone && isset( $login_status ) && $login_status != 'MO_2_FACTOR_CHALLENGE_OTP_OVER_EMAIL' ) { ?>
 
 
716
  <a name="miniorange_login_forgotphone" onclick="mologinforgotphone();"
717
  id="miniorange_login_forgotphone"
718
  class="mo2f-link"><?php echo mo2f_lt( 'Forgot Phone ?' ); ?></a>
@@ -858,7 +902,6 @@ function mo2f_customize_logo() { ?>
858
  <?php }
859
 
860
  function echo_js_css_files() {
861
-
862
  echo '<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>';
863
  echo '<script src="' . plugins_url( 'includes/js/bootstrap.min.js', dirname(dirname(__FILE__)) ) . '" ></script>';
864
  echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/twofa_style_settings.css?version=5.1.21', dirname(dirname(__FILE__))) . '" />';
248
  <?php }
249
 
250
  function mo2f_get_kba_authentication_prompt( $login_message, $redirect_to, $session_id_encrypt , $cookievalue) {
251
+
252
+ $mo2f_login_option = get_option( 'mo2f_login_option' );
253
  $mo2f_remember_device_enabled = get_option( 'mo2f_remember_device' );
254
  ?>
255
  <html>
347
  }
348
 
349
  function mo2f_get_push_notification_oobemail_prompt( $id, $login_status, $login_message, $redirect_to, $session_id_encrypt, $cookievalue ) {
350
+ global $Mo2fdbQueries,$txid;
351
  $mo2f_enable_forgotphone = get_option( 'mo2f_enable_forgotphone' );
352
  $mo2f_KBA_config_status = $Mo2fdbQueries->get_user_detail( 'mo2f_SecurityQuestions_config_status', $id );
353
  $mo2f_is_new_customer = get_option( 'mo2f_is_NC' );
354
+ $mo2f_EV_txid = get_user_meta($id,'mo2f_EV_txid',true);
355
+ if(!MO2F_IS_ONPREM)
356
+ $mo2f_EV_txid = $_SESSION['mo2f_transactionId'];
357
+ ?>
358
  <html>
359
  <head>
360
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
433
  <input type="hidden" name="miniorange_mobile_validation_failed_nonce"
434
  value="<?php echo wp_create_nonce( 'miniorange-2-factor-mobile-validation-failed-nonce' ); ?>"/>
435
  <input type="hidden" name="session_id" value="<?php echo $session_id_encrypt; ?>"/>
436
+ <input type="hidden" name="currentMethod" value="emailVer"/>
437
+
438
  </form>
439
  <form name="f" id="mo2f_mobile_validation_form" method="post" class="mo2f_display_none_forms">
440
  <input type="hidden" name="miniorange_mobile_validation_nonce"
441
  value="<?php echo wp_create_nonce( 'miniorange-2-factor-mobile-validation-nonce' ); ?>"/>
442
  <input type="hidden" name="redirect_to" value="<?php echo $redirect_to; ?>"/>
443
  <input type="hidden" name="session_id" value="<?php echo $session_id_encrypt; ?>"/>
444
+ <input type="hidden" name="TxidEmail" value="<?php echo $mo2f_EV_txid; ?>"/>
445
+
446
  </form>
447
  <form name="f" id="mo2f_show_softtoken_loginform" method="post" class="mo2f_display_none_forms">
448
  <input type="hidden" name="miniorange_softtoken"
463
  <input type="hidden" name="redirect_to" value="<?php echo $redirect_to; ?>"/>
464
  <input type="hidden" name="session_id" value="<?php echo $session_id_encrypt; ?>"/>
465
  </form>
 
466
  <script>
467
  var timeout;
468
+ var is_onprem = '<?php echo MO2F_IS_ONPREM;?>';
469
+ var calls = 0;
470
 
471
+ if(is_onprem==1)
472
+ {
473
+ pollPushValidation();
474
+ function pollPushValidation()
475
+ { calls = calls + 1;
476
+ var data = {'txid':'<?php echo $mo2f_EV_txid;?>'};
477
+ jQuery.ajax({
478
+ url: '<?php echo get_site_option("siteurl"); ?>'+"/wp-login.php",
479
+ type: "POST",
480
+ data: data,
481
+ success: function (result) {
482
+
483
+ var status = result;
484
+ if (status == 1) {
485
+ jQuery('#mo2f_mobile_validation_form').submit();
486
+ } else if (status == 'ERROR' || status == 'FAILED' || status == 'DENIED' || status ==0) {
487
+ jQuery('#mo2f_backto_mo_loginform').submit();
488
+ } else {
489
+ if(calls<300)
490
+ {
491
+ timeout = setTimeout(pollPushValidation, 1000);
492
+ }
493
+ else
494
+ {
495
+ jQuery('#mo2f_backto_mo_loginform').submit();
496
+ }
497
+ }
498
+ }
499
+ });
500
+ }
501
+
502
+
503
+ }
504
+ else
505
+ {
506
  pollPushValidation();
507
  function pollPushValidation() {
508
  var transId = "<?php echo $cookievalue;// echo MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_transactionId',$session_id_encrypt ); ?>";
527
  }
528
  });
529
  }
530
+ }
531
 
532
  function mologinoffline() {
533
  jQuery('#mo2f_show_softtoken_loginform').submit();
698
  function mo2f_get_otp_authentication_prompt( $login_status, $login_message, $redirect_to,$session_id_encrypt,$user_id ) {
699
  $mo2f_enable_forgotphone = get_option( 'mo2f_enable_forgotphone' );
700
  $mo2f_is_new_customer = get_option( 'mo2f_is_NC' );
701
+ $attempts = get_option('mo2f_attempts_before_redirect', 3);
702
+ ?>
 
703
  <html>
704
  <head>
705
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
727
  <p class="mo2fa_display_message_frontend"><?php echo $login_message; ?></p>
728
  </div>
729
  <?php } ?><br><?php
730
+ ?>
731
  <span><b>Attempts left</b>:</span> <?php echo $attempts;?><br>
732
  <?php if($attempts==1){?>
733
  <span style='color:red;'><b>If you fail to verify your identity, you will be redirected back to login page to verify your credentials.</b></span> <br>
734
  <?php }?>
735
  <br>
736
+ <div id="showOTP">
 
737
  <div class="mo2f-login-container">
738
  <form name="f" id="mo2f_submitotp_loginform" method="post">
739
  <center>
753
  <input type="hidden" name="redirect_to" value="<?php echo $redirect_to; ?>"/>
754
  <input type="hidden" name="session_id" value="<?php echo $session_id_encrypt; ?>"/>
755
  </form>
756
+ <?php
757
+ $Kbaset = get_user_meta( $user_id ,'Security Questions' );
758
+ if ( ! $mo2f_is_new_customer ) { ?>
759
+ <?php if ( $mo2f_enable_forgotphone && isset( $login_status ) && $login_status != 'MO_2_FACTOR_CHALLENGE_OTP_OVER_EMAIL' && (sizeof($Kbaset) != 0 ) ) { ?>
760
  <a name="miniorange_login_forgotphone" onclick="mologinforgotphone();"
761
  id="miniorange_login_forgotphone"
762
  class="mo2f-link"><?php echo mo2f_lt( 'Forgot Phone ?' ); ?></a>
902
  <?php }
903
 
904
  function echo_js_css_files() {
 
905
  echo '<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>';
906
  echo '<script src="' . plugins_url( 'includes/js/bootstrap.min.js', dirname(dirname(__FILE__)) ) . '" ></script>';
907
  echo '<link rel="stylesheet" type="text/css" href="' . plugins_url( 'includes/css/twofa_style_settings.css?version=5.1.21', dirname(dirname(__FILE__))) . '" />';
controllers/twofa/setup_twofa.php CHANGED
@@ -7,4 +7,27 @@
7
  $email_registered = 1;
8
  else
9
  $email_registered = 0;
10
- include $dirName .'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'setup_twofa.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  $email_registered = 1;
8
  else
9
  $email_registered = 0;
10
+
11
+ if(current_user_can( 'manage_options' ) && isset($_POST['option']))
12
+ {
13
+ switch($_POST['option'])
14
+ {
15
+ case "mo2f_enable_2FA_on_login_page_option":
16
+ wpns_handle_enable_2fa_login_prompt($_POST); break;
17
+ }
18
+ }
19
+
20
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'setup_twofa.php';
21
+
22
+ function wpns_handle_enable_2fa_login_prompt($postvalue)
23
+ {
24
+ if( get_option( 'mo2f_enable_2fa_prompt_on_login_page' ) == 1 )
25
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('TWO_FA_ON_LOGIN_PROMPT_ENABLED'),'SUCCESS');
26
+ else{
27
+ if(isset($postvalue['mo2f_enable_2fa_prompt_on_login_page'])){
28
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('TWO_FA_PROMPT_LOGIN_PAGE'),'ERROR');
29
+ }else{
30
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('TWO_FA_ON_LOGIN_PROMPT_DISABLED'),'ERROR');
31
+ }
32
+ }
33
+ }
controllers/twofa/two_fa.php CHANGED
@@ -1,4 +1,4 @@
1
  <?php
2
 
3
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa.php';
4
  update_site_option('mo2f_two_factor',true);
1
  <?php
2
 
3
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa.php';
4
  update_site_option('mo2f_two_factor',true);
controllers/twofa/two_fa_addon.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
2
  global $Mo2fdbQueries;
 
3
  $mo2f_user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $current_user->ID );
4
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_addon.php';
1
  <?php
2
  global $Mo2fdbQueries;
3
+ $current_user = wp_get_current_user();
4
  $mo2f_user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $current_user->ID );
5
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_addon.php';
controllers/twofa/two_fa_custom_form.php CHANGED
@@ -1,2 +1,2 @@
1
  <?php
2
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_custom_form.php';
1
  <?php
2
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_custom_form.php';
controllers/twofa/two_fa_custom_login.php CHANGED
@@ -1,3 +1,3 @@
1
  <?php
2
 
3
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_custom_login.php';
1
  <?php
2
 
3
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_custom_login.php';
controllers/twofa/two_fa_login_option.php CHANGED
@@ -1,2 +1,2 @@
1
  <?php
2
- include_once $dirName .'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_login_option.php';
1
  <?php
2
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_login_option.php';
controllers/twofa/two_fa_rba.php CHANGED
@@ -1,3 +1,3 @@
1
  <?php
2
 
3
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_rba.php';
1
  <?php
2
 
3
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_rba.php';
controllers/twofa/two_fa_shortcode.php CHANGED
@@ -1,3 +1,3 @@
1
  <?php
2
 
3
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_shortcode.php';
1
  <?php
2
 
3
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_shortcode.php';
controllers/twofa/two_fa_unlimittedUser.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+
2
+ <?php
3
+ global $moWpnsUtility, $mo2f_dirName;
4
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_unlimittedUser.php';
controllers/twofa/two_fa_unlimittedUser_ajax.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WPNS_unlimittedUser
4
+ {
5
+ function __construct(){
6
+
7
+ add_action( 'admin_init' , array( $this, 'mo_two_fa_unlimittedUser_ajax' ));
8
+ }
9
+
10
+ function mo_two_fa_unlimittedUser_ajax(){
11
+ add_action( 'wp_ajax_wpns_two_fa_unlimittedUser', array($this,'wpns_two_fa_unlimittedUser') );
12
+ }
13
+
14
+ function wpns_two_fa_unlimittedUser(){
15
+ switch($_POST['wpns_unlimittedUser_ajax'])
16
+ {
17
+ case 'save':
18
+ $this->wpns_handle_save(); break;
19
+ }
20
+ }
21
+ function wpns_handle_save()
22
+ {
23
+
24
+ if ( !wp_verify_nonce($_POST['nonce'],'unlimittedUserNonce') ){
25
+ wp_send_json('ERROR');
26
+ return;
27
+ }
28
+ global $wp_roles;
29
+ if (!isset($wp_roles))
30
+ $wp_roles = new WP_Roles();
31
+ foreach($wp_roles->role_names as $id => $name) {
32
+ update_option('mo2fa_'.$id, 0);
33
+ }
34
+ $enabledrole = $_POST['enabledrole'];
35
+ foreach($enabledrole as $role){
36
+ update_option($role, 1);
37
+ }
38
+ update_option('mo2fa_author_login_url',$_POST['mo2fa_author_login_url']);
39
+ update_option('mo2fa_subscriber_login_url',$_POST['mo2fa_subscriber_login_url']);
40
+ update_option('mo2fa_contributor_login_url',$_POST['mo2fa_contributor_login_url']);
41
+ update_option('mo2fa_editor_login_url',$_POST['mo2fa_editor_login_url']);
42
+ update_option('mo2fa_administrator_login_url',$_POST['mo2fa_administrator_login_url']);
43
+ wp_send_json('true');
44
+ return;
45
+ }
46
+ }new WPNS_unlimittedUser();
47
+ ?>
controllers/twofa/two_fa_video_guide.php CHANGED
@@ -1,4 +1,4 @@
1
  <?php
2
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_video_guide.php';
3
 
4
 
1
  <?php
2
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_video_guide.php';
3
 
4
 
controllers/twofa/two_factor_ajax.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class mo_2f_ajax
3
+ {
4
+ function __construct(){
5
+
6
+ add_action( 'admin_init' , array( $this, 'mo_2f_two_factor' ) );
7
+ }
8
+
9
+ function mo_2f_two_factor(){
10
+ add_action( 'wp_ajax_mo_two_factor_ajax', array($this,'mo_two_factor_ajax') );
11
+ }
12
+
13
+ function mo_two_factor_ajax(){
14
+ switch ($_POST['mo_2f_two_factor_ajax']) {
15
+ case 'mo2f_save_email_verification':
16
+ $this->mo2f_save_email_verification(); break;
17
+ case 'mo2f_unlimitted_user':
18
+ $this->mo2f_unlimitted_user();break;
19
+ case 'CheckEVStatus':
20
+ $this->CheckEVStatus(); break;
21
+ case 'mo2f_role_based_2_factor':
22
+ $this->mo2f_role_based_2_factor();break;
23
+ case 'mo2f_enable_disable_twofactor':
24
+ $this->mo2f_enable_disable_twofactor(); break;
25
+ case 'mo2f_shift_to_onprem':
26
+ $this->mo2f_shift_to_onprem();break;
27
+ }
28
+ }
29
+ function mo2f_shift_to_onprem(){
30
+ update_option('is_onprem', 1);
31
+ update_option( 'mo2f_remember_device',0);
32
+ wp_send_json('true');
33
+ }
34
+
35
+
36
+ function mo2f_enable_disable_twofactor(){
37
+ $nonce = sanitize_text_field($_POST['mo2f_nonce_enable_2FA']);
38
+
39
+ if ( ! wp_verify_nonce( $nonce, 'mo2f-nonce-enable-2FA' ) ) {
40
+ $error = new WP_Error();
41
+ $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
42
+
43
+ //return $error;
44
+ }
45
+
46
+ $enable = sanitize_text_field($_POST['mo2f_enable_2fa']);
47
+ if($enable == 'true'){
48
+ update_site_option('mo2f_activate_plugin' , true);
49
+ wp_send_json('true');
50
+ }
51
+ else{
52
+ update_site_option('mo2f_activate_plugin' , false);
53
+ wp_send_json('false');
54
+ }
55
+ }
56
+
57
+ function mo2f_role_based_2_factor(){
58
+ if ( !wp_verify_nonce($_POST['nonce'],'unlimittedUserNonce') ){
59
+ wp_send_json('ERROR');
60
+ return;
61
+ }
62
+ global $wp_roles;
63
+ if (!isset($wp_roles))
64
+ $wp_roles = new WP_Roles();
65
+ foreach($wp_roles->role_names as $id => $name) {
66
+ update_option('mo2fa_'.$id, 0);
67
+ }
68
+
69
+ if(isset($_POST['enabledrole'])){
70
+ $enabledrole = $_POST['enabledrole'];
71
+ }
72
+ else{
73
+ $enabledrole = array();
74
+ }
75
+ foreach($enabledrole as $role){
76
+ update_option($role, 1);
77
+ }
78
+ //update_option('mo2fa_administrator_login_url',$_POST['mo2fa_administrator_login_url']);
79
+ wp_send_json('true');
80
+ return;
81
+ }
82
+
83
+
84
+ function mo2f_unlimitted_user()
85
+ {
86
+ if(!wp_verify_nonce($_POST['nonce'],'unlimittedUserNonce'))
87
+ {
88
+ echo "NonceDidNotMatch";
89
+ exit;
90
+ }
91
+ else
92
+ {
93
+ if($_POST['enableOnPremise'] == 'on')
94
+ {
95
+ global $wp_roles;
96
+ if (!isset($wp_roles))
97
+ $wp_roles = new WP_Roles();
98
+ foreach($wp_roles->role_names as $id => $name) {
99
+ add_site_option('mo2fa_'.$id, 1);
100
+ if($id == 'administrator'){
101
+ add_option('mo2fa_'.$id.'_login_url',admin_url());
102
+ }else{
103
+ add_option('mo2fa_'.$id.'_login_url',home_url());
104
+ }
105
+ }
106
+ //update_option('is_onprem' ,1);
107
+ echo "OnPremiseActive";
108
+ exit;
109
+ }
110
+ else
111
+ {
112
+ //update_option('is_onprem' ,0);
113
+ echo "OnPremiseDeactive";
114
+ exit;
115
+ }
116
+ }
117
+ }
118
+ function mo2f_save_email_verification()
119
+ {
120
+
121
+ if(!wp_verify_nonce($_POST['nonce'],'EmailVerificationSaveNonce'))
122
+ {
123
+ echo "NonceDidNotMatch";
124
+ exit;
125
+ }
126
+ else
127
+ {
128
+
129
+ $email = sanitize_text_field($_POST['email']);
130
+ $error = false;
131
+ $user_id = sanitize_text_field($_POST['user_id']);
132
+ $onprem = MO2F_IS_ONPREM;
133
+ if($onprem)
134
+ {
135
+ $twofactor_transactions = new Mo2fDB;
136
+ $exceeded = $twofactor_transactions->check_user_limit_exceeded($user_id);
137
+
138
+ if($exceeded){
139
+ echo "USER_LIMIT_EXCEEDED";
140
+ exit;
141
+ }
142
+ }
143
+ if (!filter_var($email, FILTER_VALIDATE_EMAIL))
144
+ {
145
+ $error = true;
146
+ }
147
+ if($email!='' && !$error)
148
+ {
149
+ global $Mo2fdbQueries;
150
+ update_option('is_onprem' , 1);
151
+ $Mo2fdbQueries->update_user_details(get_current_user_id(),array('mo2f_EmailVerification_config_status'=>true));
152
+ $Mo2fdbQueries->update_user_details(get_current_user_id(),array('mo2f_configured_2FA_method'=>"Email Verification"));
153
+ update_user_meta($user_id,'email',$email);
154
+ echo "settingsSaved";
155
+ exit;
156
+ }
157
+ else
158
+ {
159
+ echo "invalidEmail";
160
+ exit;
161
+ }
162
+
163
+ }
164
+
165
+ }
166
+ function CheckEVStatus()
167
+ {
168
+ if(isset($_POST['txid']))
169
+ {
170
+ $txid = sanitize_text_field($_POST['txid']);
171
+ $status = get_site_option($_POST['txid']);
172
+ if($status ==1 || $status ==0)
173
+ delete_site_option($_POST['txid']);
174
+ echo $status;
175
+ exit();
176
+ }
177
+ echo "empty txid";
178
+ exit;
179
+ }
180
+
181
+
182
+ }
183
+
184
+ new mo_2f_ajax;
185
+ ?>
controllers/upgrade.php CHANGED
@@ -1,2 +1,2 @@
1
  <?php
2
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'upgrade.php';
1
  <?php
2
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'upgrade.php';
controllers/waf.php CHANGED
@@ -1,17 +1,17 @@
1
  <?php
2
- global $moWpnsUtility,$dirName;
3
  $mo_wpns_handler = new MoWpnsHandler();
4
  $sqlC = $mo_wpns_handler->get_blocked_attacks_count("SQL");
5
  $rceC = $mo_wpns_handler->get_blocked_attacks_count("RCE");
6
  $rfiC = $mo_wpns_handler->get_blocked_attacks_count("RFI");
7
  $lfiC = $mo_wpns_handler->get_blocked_attacks_count("LFI");
8
  $xssC = $mo_wpns_handler->get_blocked_attacks_count("XSS");
9
- $totalAttacks = $sqlC+$lfiC+$rfiC+$xssC+$rceC;
10
- $manualBlocks = $mo_wpns_handler->get_manual_blocked_ip_count();
11
  $realTime = 0;
12
- $countryBlocked = $mo_wpns_handler->get_blocked_countries();
13
- $IPblockedByWAF = $mo_wpns_handler->get_blocked_ip_waf();
14
- $totalIPBlocked = $manualBlocks+$realTime+$IPblockedByWAF;
15
  $mo_waf = get_site_option('WAFEnabled');
16
  if($mo_waf)
17
  {
@@ -22,8 +22,12 @@
22
  $mo_waf = true;
23
  }
24
 
25
- $img_loader_url = plugins_url('wp-security-pro/includes/images/loader.gif');
26
-
 
 
 
 
27
  if($totalIPBlocked>999)
28
  {
29
  $totalIPBlocked = strval(intval($totalIPBlocked/1000)).'k+';
@@ -35,7 +39,7 @@
35
  }
36
  update_site_option('mo2f_visit_waf',true);
37
 
38
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'waf.php';
39
 
40
 
41
 
1
  <?php
2
+ global $moWpnsUtility,$mo2f_dirName;
3
  $mo_wpns_handler = new MoWpnsHandler();
4
  $sqlC = $mo_wpns_handler->get_blocked_attacks_count("SQL");
5
  $rceC = $mo_wpns_handler->get_blocked_attacks_count("RCE");
6
  $rfiC = $mo_wpns_handler->get_blocked_attacks_count("RFI");
7
  $lfiC = $mo_wpns_handler->get_blocked_attacks_count("LFI");
8
  $xssC = $mo_wpns_handler->get_blocked_attacks_count("XSS");
9
+ $totalAttacks = $sqlC+$lfiC+$rfiC+$xssC+$rceC;
10
+ $manualBlocks = $mo_wpns_handler->get_manual_blocked_ip_count();
11
  $realTime = 0;
12
+ $countryBlocked = $mo_wpns_handler->get_blocked_countries();
13
+ $IPblockedByWAF = $mo_wpns_handler->get_blocked_ip_waf();
14
+ $totalIPBlocked = $manualBlocks+$realTime+$IPblockedByWAF;
15
  $mo_waf = get_site_option('WAFEnabled');
16
  if($mo_waf)
17
  {
22
  $mo_waf = true;
23
  }
24
 
25
+
26
+ $path = dirname(dirname(__FILE__)).'/includes/images/loader.gif';
27
+ $path = explode('plugins', $path);
28
+
29
+
30
+ $img_loader_url = plugins_url().'/'.$path[1];
31
  if($totalIPBlocked>999)
32
  {
33
  $totalIPBlocked = strval(intval($totalIPBlocked/1000)).'k+';
39
  }
40
  update_site_option('mo2f_visit_waf',true);
41
 
42
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'waf.php';
43
 
44
 
45
 
controllers/wpns-loginsecurity-ajax.php CHANGED
@@ -30,8 +30,6 @@ class wpns_ajax
30
  $this->wpns_waf_rate_limiting_form(); break;
31
  case 'wpns_ip_lookup':
32
  $this->wpns_ip_lookup(); break;
33
- case 'wpns_save_email_verification':
34
- $this->wpns_save_email_verification(); break;
35
  }
36
  }
37
 
@@ -70,7 +68,7 @@ class wpns_ajax
70
  function wpns_handle_IP_blocking()
71
  {
72
 
73
- global $dirName;
74
  if(!wp_verify_nonce($_POST['nonce'],'manualIPBlockingNonce'))
75
  {
76
  echo "NonceDidNotMatch";
@@ -78,12 +76,12 @@ class wpns_ajax
78
  }
79
  else
80
  {
81
- include_once($dirName.'controllers'.DIRECTORY_SEPARATOR.'ip-blocking.php');
82
  }
83
  }
84
  function wpns_whitelist_ip()
85
  {
86
- global $dirName;
87
  if(!wp_verify_nonce($_POST['nonce'],'IPWhiteListingNonce'))
88
  {
89
  echo "NonceDidNotMatch";
@@ -91,44 +89,10 @@ class wpns_ajax
91
  }
92
  else
93
  {
94
- include_once($dirName.'controllers'.DIRECTORY_SEPARATOR.'ip-blocking.php');
95
  }
96
  }
97
- function wpns_save_email_verification()
98
- {
99
- if(!wp_verify_nonce($_POST['nonce'],'EmailVerificationSaveNonce'))
100
- {
101
- echo "NonceDidNotMatch";
102
- exit;
103
- }
104
- else
105
- {
106
- $email = sanitize_text_field($_POST['email']);
107
- $error = false;
108
- $user_id = sanitize_text_field($_POST['user_id']);
109
 
110
- if (!filter_var($email, FILTER_VALIDATE_EMAIL))
111
- {
112
- $error = true;
113
- }
114
- if($email!='' && !$error)
115
- {
116
- global $Mo2fdbQueries;
117
- $Mo2fdbQueries->update_user_details(get_current_user_id(),array('mo2f_EmailVerification_config_status'=>true));
118
- $Mo2fdbQueries->update_user_details(get_current_user_id(),array('mo2f_configured_2FA_method'=>"Email Verification"));
119
- update_user_meta($user_id,'email',$email);
120
- echo "settingsSaved";
121
- exit;
122
- }
123
- else
124
- {
125
- echo "invalidEmail";
126
- exit;
127
- }
128
-
129
- }
130
-
131
- }
132
  function wpns_ip_lookup()
133
  {
134
 
@@ -499,13 +463,6 @@ class wpns_ajax
499
  $cont .= '# END miniOrange WAF'.PHP_EOL;
500
  file_put_contents($dir_name, $cont);
501
 
502
-
503
- // $content = explode('<IfModule mod_rewrite.c>', $file);
504
- // $content[0].= '<IfModule mod_rewrite.c>'.PHP_EOL;
505
- // $content[0].= 'php_value auto_prepend_file '.$dir_name1.'mo-check.php'.PHP_EOL;
506
- // $content[0].= $content[1];
507
- // file_put_contents($dir_name, $content[0]);
508
-
509
  $filecontent = file_get_contents($dir_name);
510
 
511
  $dir_name = dirname(__FILE__);
@@ -1129,7 +1086,7 @@ class wpns_ajax
1129
  $reg_form_captcha = $_POST['registeration_form'];
1130
  if($reg_form_captcha == 'true'){$reg_form_captcha = "on";}else if($reg_form_captcha == 'false') {$reg_form_captcha = "";}
1131
 
1132
- if(($site_key == "" || $secret_key == "")){
1133
  wp_send_json('empty');
1134
  return;
1135
  }
30
  $this->wpns_waf_rate_limiting_form(); break;
31
  case 'wpns_ip_lookup':
32
  $this->wpns_ip_lookup(); break;
 
 
33
  }
34
  }
35
 
68
  function wpns_handle_IP_blocking()
69
  {
70
 
71
+ global $mo2f_dirName;
72
  if(!wp_verify_nonce($_POST['nonce'],'manualIPBlockingNonce'))
73
  {
74
  echo "NonceDidNotMatch";
76
  }
77
  else
78
  {
79
+ include_once($mo2f_dirName.'controllers'.DIRECTORY_SEPARATOR.'ip-blocking.php');
80
  }
81
  }
82
  function wpns_whitelist_ip()
83
  {
84
+ global $mo2f_dirName;
85
  if(!wp_verify_nonce($_POST['nonce'],'IPWhiteListingNonce'))
86
  {
87
  echo "NonceDidNotMatch";
89
  }
90
  else
91
  {
92
+ include_once($mo2f_dirName.'controllers'.DIRECTORY_SEPARATOR.'ip-blocking.php');
93
  }
94
  }
 
 
 
 
 
 
 
 
 
 
 
 
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  function wpns_ip_lookup()
97
  {
98
 
463
  $cont .= '# END miniOrange WAF'.PHP_EOL;
464
  file_put_contents($dir_name, $cont);
465
 
 
 
 
 
 
 
 
466
  $filecontent = file_get_contents($dir_name);
467
 
468
  $dir_name = dirname(__FILE__);
1086
  $reg_form_captcha = $_POST['registeration_form'];
1087
  if($reg_form_captcha == 'true'){$reg_form_captcha = "on";}else if($reg_form_captcha == 'false') {$reg_form_captcha = "";}
1088
 
1089
+ if(($site_key == "" || $secret_key == "") and $enable_captcha == 'true'){
1090
  wp_send_json('empty');
1091
  return;
1092
  }
database/database_functions.php CHANGED
@@ -13,7 +13,8 @@
13
  private $skipfiles;
14
  private $hashfile;
15
 
16
- function __construct(){
 
17
  global $wpdb;
18
  $this->transactionTable = $wpdb->base_prefix.'mo2f_network_transactions';
19
  $this->blockedIPsTable = $wpdb->base_prefix.'mo2f_network_blocked_ips';
@@ -30,7 +31,8 @@
30
  $this->filescan = $wpdb->base_prefix.'wpns_files_scan';
31
  }
32
 
33
- function mo_plugin_activate(){
 
34
  global $wpdb;
35
  if(!get_option('mo_wpns_dbversion')||get_option('mo_wpns_dbversion')<MoWpnsConstants::DB_VERSION){
36
  update_option('mo_wpns_dbversion', MoWpnsConstants::DB_VERSION );
@@ -78,9 +80,14 @@
78
  if($wpdb->get_var("show tables like '$tableName'") != $tableName)
79
  {
80
  $sql = "CREATE TABLE " . $tableName . " (`id` int NOT NULL AUTO_INCREMENT,
81
- `backup_id` mediumtext NOT NULL, `file_name` mediumtext NOT NULL , `created_timestamp` bigint,UNIQUE KEY id (id) );";
82
  dbDelta($sql);
83
  }
 
 
 
 
 
84
 
85
  $tableName = $this->emailAuditTable;
86
  if($wpdb->get_var("show tables like '$tableName'") != $tableName)
@@ -113,7 +120,7 @@
113
  if($wpdb->get_var("show tables like '$tableName'") != $tableName)
114
  {
115
  $sql = "CREATE TABLE " . $tableName . " (
116
- `id` bigint NOT NULL AUTO_INCREMENT, `scan_mode` mediumtext NOT NULL, `scanned_folders` mediumtext NOT NULL, `scanned_files` int, `malware_count` int NOT NULL DEFAULT 0, `repo_issues` int NOT NULL DEFAULT 0, `malicious_links` int NOT NULL DEFAULT 0, `start_timestamp` int, `completed_timestamp` int, UNIQUE KEY id (id) );";
117
  dbDelta($sql);
118
  }
119
  $result= $wpdb->get_var("SHOW COLUMNS FROM `$tableName` LIKE 'scan_mode'");
@@ -155,6 +162,7 @@
155
  `id` bigint(20) NOT NULL AUTO_INCREMENT,`file name` varchar(500) NOT NULL,`file hash` mediumtext NOT NULL, `scan_data` mediumtext NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`), UNIQUE KEY `file name` (`file name`), UNIQUE KEY `id_2`(`id`));";
156
  dbDelta($sql);
157
  }
 
158
  $row1 = $wpdb->get_results( "SHOW COLUMNS FROM ".$this->malwarereportTable." LIKE 'malware_count'" );
159
  $row2 = $wpdb->get_results( "SHOW COLUMNS FROM ".$this->malwarereportTable." LIKE 'repo_issues'" );
160
  $row3 = $wpdb->get_results( "SHOW COLUMNS FROM ".$this->malwarereportTable." LIKE 'malicious_links'" );
@@ -174,6 +182,51 @@
174
  $result = $wpdb->query("ALTER TABLE $this->hashfile ADD COLUMN `scan_data` mediumtext NOT NULL");
175
  }
176
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
  function get_ip_blocked_count($ipAddress)
179
  {
@@ -290,33 +343,6 @@
290
  );
291
  }
292
 
293
- function insert_backup_detail($backup_id,$file_name,$backup_created_timestamp){
294
-
295
- global $wpdb;
296
- $wpdb->insert(
297
- $this->backupdetails,
298
- array(
299
- 'backup_id' =>$backup_id,
300
- 'file_name' =>$file_name,
301
- 'created_timestamp'=> $backup_created_timestamp
302
- )
303
- );
304
- }
305
-
306
- function get_number_of_plugin_backup(){
307
- global $wpdb;
308
-
309
-
310
- $plugin_count = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE backup_id = 'plugin'");
311
- $themes_count = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE backup_id = 'themes'");
312
- $wp_files_count = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE backup_id = 'wpfiles'");
313
- $db_count = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE backup_id = 'db'");
314
- $total_backup = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails);
315
- $array = array('plugin_count'=>$plugin_count,'themes_count'=>$themes_count,'wp_files_count'=>$wp_files_count,'db_count'=>$db_count,'total_backup'=>$total_backup);
316
-
317
- return $array;
318
- }
319
-
320
  function get_number_of_whitelisted_ips(){
321
  global $wpdb;
322
  return $wpdb->get_var("SELECT COUNT(*) FROM ".$this->whitelistIPsTable."");
@@ -731,6 +757,29 @@
731
  return $result;
732
  }
733
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
734
  function mo_wpns_get_scan_count($result){
735
  $scan_count = 0;
736
  $repo_count = 0;
13
  private $skipfiles;
14
  private $hashfile;
15
 
16
+ function __construct()
17
+ {
18
  global $wpdb;
19
  $this->transactionTable = $wpdb->base_prefix.'mo2f_network_transactions';
20
  $this->blockedIPsTable = $wpdb->base_prefix.'mo2f_network_blocked_ips';
31
  $this->filescan = $wpdb->base_prefix.'wpns_files_scan';
32
  }
33
 
34
+ function mo_plugin_activate()
35
+ {
36
  global $wpdb;
37
  if(!get_option('mo_wpns_dbversion')||get_option('mo_wpns_dbversion')<MoWpnsConstants::DB_VERSION){
38
  update_option('mo_wpns_dbversion', MoWpnsConstants::DB_VERSION );
80
  if($wpdb->get_var("show tables like '$tableName'") != $tableName)
81
  {
82
  $sql = "CREATE TABLE " . $tableName . " (`id` int NOT NULL AUTO_INCREMENT,
83
+ `backup_id` mediumtext NOT NULL, `file_name` mediumtext NOT NULL , `created_timestamp` bigint, `plugin_path` mediumtext, UNIQUE KEY id (id) );";
84
  dbDelta($sql);
85
  }
86
+ $result= $wpdb->get_var("SHOW COLUMNS FROM `$tableName` LIKE 'plugin_path'");
87
+ if(is_null($result)){
88
+ $sql = "ALTER TABLE `$tableName` ADD `plugin_path` mediumtext AFTER `created_timestamp` ;";
89
+ $results1 = $wpdb->query($sql);
90
+ }
91
 
92
  $tableName = $this->emailAuditTable;
93
  if($wpdb->get_var("show tables like '$tableName'") != $tableName)
120
  if($wpdb->get_var("show tables like '$tableName'") != $tableName)
121
  {
122
  $sql = "CREATE TABLE " . $tableName . " (
123
+ `id` bigint NOT NULL AUTO_INCREMENT, `scan_mode` mediumtext NOT NULL, `scanned_folders` mediumtext NOT NULL, `scanned_files` int NOT NULL, `malware_count` int NOT NULL DEFAULT 0, `repo_issues` int NOT NULL DEFAULT 0, `malicious_links` int NOT NULL DEFAULT 0, `start_timestamp` int, `completed_timestamp` int, UNIQUE KEY id (id) );";
124
  dbDelta($sql);
125
  }
126
  $result= $wpdb->get_var("SHOW COLUMNS FROM `$tableName` LIKE 'scan_mode'");
162
  `id` bigint(20) NOT NULL AUTO_INCREMENT,`file name` varchar(500) NOT NULL,`file hash` mediumtext NOT NULL, `scan_data` mediumtext NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`), UNIQUE KEY `file name` (`file name`), UNIQUE KEY `id_2`(`id`));";
163
  dbDelta($sql);
164
  }
165
+
166
  $row1 = $wpdb->get_results( "SHOW COLUMNS FROM ".$this->malwarereportTable." LIKE 'malware_count'" );
167
  $row2 = $wpdb->get_results( "SHOW COLUMNS FROM ".$this->malwarereportTable." LIKE 'repo_issues'" );
168
  $row3 = $wpdb->get_results( "SHOW COLUMNS FROM ".$this->malwarereportTable." LIKE 'malicious_links'" );
182
  $result = $wpdb->query("ALTER TABLE $this->hashfile ADD COLUMN `scan_data` mediumtext NOT NULL");
183
  }
184
  }
185
+
186
+ function insert_backup_detail($backup_id,$file_name,$backup_created_timestamp,$plugin_path){
187
+ global $wpdb;
188
+ $wpdb->insert(
189
+ $this->backupdetails,
190
+ array(
191
+ 'backup_id' =>$backup_id,
192
+ 'file_name' =>$file_name,
193
+ 'created_timestamp'=> $backup_created_timestamp,
194
+ 'plugin_path' => $plugin_path
195
+ ));
196
+ }
197
+
198
+ function get_table_content(){
199
+ global $wpdb;
200
+ return $wpdb->get_results("SELECT plugin_path,file_name,created_timestamp,id FROM ".$this->backupdetails);
201
+ }
202
+
203
+ function get_number_of_plugin_backup(){
204
+ global $wpdb;
205
+
206
+ $plugin_count = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE backup_id = 'plugin'");
207
+ $themes_count = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE backup_id = 'themes'");
208
+ $wp_files_count = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE backup_id = 'wpfiles'");
209
+ $db_count = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE backup_id = 'db'");
210
+ $total_backup = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails);
211
+ $array = array('plugin_count'=>$plugin_count,'themes_count'=>$themes_count,'wp_files_count'=>$wp_files_count,'db_count'=>$db_count,'total_backup'=>$total_backup);
212
+
213
+ return $array;
214
+ }
215
+
216
+ function delete_file($id){
217
+ global $wpdb;
218
+ $wpdb->query(
219
+ "DELETE FROM ".$this->backupdetails."
220
+ WHERE id = ".$id
221
+ );
222
+ return;
223
+ }
224
+
225
+ function row_exist($id){
226
+ global $wpdb;
227
+ $is_exist = $wpdb->get_var("SELECT COUNT(*) FROM ".$this->backupdetails." WHERE id =".$id );
228
+ return $is_exist;
229
+ }
230
 
231
  function get_ip_blocked_count($ipAddress)
232
  {
343
  );
344
  }
345
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  function get_number_of_whitelisted_ips(){
347
  global $wpdb;
348
  return $wpdb->get_var("SELECT COUNT(*) FROM ".$this->whitelistIPsTable."");
757
  return $result;
758
  }
759
 
760
+ function mo_wpns_upgrade_process_complete(){
761
+ $current_db_version = get_option('mo_wpns_dbversion');
762
+ if($current_db_version < MoWpnsConstants::DB_VERSION){
763
+ update_option('mo_wpns_dbversion', MoWpnsConstants::DB_VERSION );
764
+ $row = $wpdb->get_results( "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '".$this->malwarereportTable."' AND column_name = 'malware_count' AND column_name='repo_issues' AND column_name='malicious_links'" );
765
+ if(empty($row)){
766
+ $result = $wpdb->query("ALTER TABLE $this->malwarereportTable ADD COLUMN `malware_count` INT NOT NULL DEFAULT 0 AFTER `scanned_files`, ADD COLUMN `repo_issues` INT NOT NULL DEFAULT 0 AFTER `malware_count`, ADD COLUMN `malicious_links` INT NOT NULL DEFAULT 0 AFTER `repo_issues`");
767
+ if($result){
768
+ $report_ids = $wpdb->get_results("SELECT id FROM $this->malwarereportTable");
769
+ foreach ($report_ids as $key => $value) {
770
+ $scan_detail = $wpdb->get_results("SELECT report FROM $this->scanreportdetails WHERE report_id='".$report_ids[$key]->id."'");
771
+ $result = $this->mo_wpns_get_scan_count($scan_detail);
772
+ $wpdb->query("UPDATE $this->malwarereportTable SET 'malware_count'= '".$result['scan']."', `repo_issues`='".$result['repo']."', `malicious_links`='".$result['extl']."' WHERE id='".$report_ids[$key]->id."'");
773
+ }
774
+ }
775
+ }
776
+ $rowhash = $wpdb->get_results( "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '".$this->hashfile."' AND column_name = 'scan_data'" );
777
+ if(empty($rowhash)){
778
+ $result = $wpdb->query("ALTER TABLE $this->hashfile ADD COLUMN `scan_data` mediumtext NOT NULL");
779
+ }
780
+ }
781
+ }
782
+
783
  function mo_wpns_get_scan_count($result){
784
  $scan_count = 0;
785
  $repo_count = 0;
database/database_functions_2fa.php CHANGED
@@ -261,5 +261,24 @@ class Mo2fDB {
261
 
262
  return;
263
  }
 
264
 
265
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
 
262
  return;
263
  }
264
+ function check_user_limit_exceeded($user_id){
265
 
266
+ global $wpdb;
267
+ $value = $wpdb->query(
268
+ "SELECT meta_key FROM ".$wpdb->base_prefix ."usermeta
269
+ WHERE meta_key = 'currentMethod'"
270
+ );
271
+
272
+ $user_already_configured = $wpdb->query(
273
+ "SELECT meta_key FROM ".$wpdb->base_prefix ."usermeta
274
+ WHERE meta_key = 'currentMethod' and user_id =".$user_id );
275
+
276
+ if($value < 3 || $user_already_configured){
277
+ return false;
278
+ }
279
+ else{
280
+ return true;
281
+ }
282
+ }
283
+
284
+ }
handler/WAF/database/mo-waf-db.php CHANGED
@@ -196,8 +196,11 @@
196
  if($results)
197
  {
198
  $rows = mysqli_fetch_array($results);
199
- $option_value = intval($rows['option_value']);
200
- return $option_value;
 
 
 
201
  }
202
  return '';
203
  }
196
  if($results)
197
  {
198
  $rows = mysqli_fetch_array($results);
199
+ if(!is_null($rows['option_value']))
200
+ {
201
+ $option_value = intval($rows['option_value']);
202
+ return $option_value;
203
+ }
204
  }
205
  return '';
206
  }
handler/WAF/mo-waf-plugin.php CHANGED
@@ -6,8 +6,8 @@
6
  $wafInclude = $dir[0].'/handler/WAF/waf-include.php';
7
  $pluginU = $dir[0].'helper/pluginUtility.php';
8
  $wafDB = $dir[0].'/handler/WAF/database/mo-waf-plugin-db.php';
9
- $errorPage = $dir[0].'handler/mo-error.php';
10
- $blockPage = $dir[0].'handler/mo-block.php';
11
 
12
  include_once($wafInclude);
13
  include_once($pluginU);
@@ -23,6 +23,7 @@
23
  {
24
  header('HTTP/1.1 403 Forbidden');
25
  include_once($blockPage);
 
26
  }
27
  }
28
  $fileName = setting_file();
@@ -47,6 +48,7 @@
47
  {
48
  header('HTTP/1.1 403 Forbidden');
49
  include_once($errorPage);
 
50
  }
51
  if($RateLimitingCrawler == '1')
52
  {
@@ -57,18 +59,21 @@
57
  }
58
  }
59
  $attack = array();
60
- if($SQL==1)
61
- {
62
- array_push($attack,"SQL");
63
- }
64
- if($XSS==1)
65
- {
66
- array_push($attack,"XSS");
67
- }
68
- if($LFI==1)
69
- {
70
- array_push($attack,"LFI");
71
- }
 
 
 
72
 
73
  $attackC = $attack;
74
  $ParanoiaLevel = 1;
@@ -122,6 +127,7 @@
122
 
123
  header('HTTP/1.1 403 Forbidden');
124
  include_once($errorPage);
 
125
  }
126
  }
127
  }
@@ -153,6 +159,7 @@
153
  }
154
  header('HTTP/1.1 403 Forbidden');
155
  include_once($errorPage);
 
156
  }
157
  }
158
  function applyRateLimitingCrawler($ipaddress,$filename,$errorPage)
@@ -192,6 +199,7 @@
192
  }
193
  header('HTTP/1.1 403 Forbidden');
194
  include_once($errorPage);
 
195
  }
196
  }
197
  }
6
  $wafInclude = $dir[0].'/handler/WAF/waf-include.php';
7
  $pluginU = $dir[0].'helper/pluginUtility.php';
8
  $wafDB = $dir[0].'/handler/WAF/database/mo-waf-plugin-db.php';
9
+ $errorPage = $dir[0].'handler/mo-error.html';
10
+ $blockPage = $dir[0].'handler/mo-block.html';
11
 
12
  include_once($wafInclude);
13
  include_once($pluginU);
23
  {
24
  header('HTTP/1.1 403 Forbidden');
25
  include_once($blockPage);
26
+ exit;
27
  }
28
  }
29
  $fileName = setting_file();
48
  {
49
  header('HTTP/1.1 403 Forbidden');
50
  include_once($errorPage);
51
+ exit;
52
  }
53
  if($RateLimitingCrawler == '1')
54
  {
59
  }
60
  }
61
  $attack = array();
62
+ if(isset($SQL) )
63
+ {
64
+ if($SQL==1)
65
+ array_push($attack,"SQL");
66
+ }
67
+ if(isset($XSS) )
68
+ {
69
+ if( $XSS==1)
70
+ array_push($attack,"XSS");
71
+ }
72
+ if(isset($LFI))
73
+ {
74
+ if($LFI==1)
75
+ array_push($attack,"LFI");
76
+ }
77
 
78
  $attackC = $attack;
79
  $ParanoiaLevel = 1;
127
 
128
  header('HTTP/1.1 403 Forbidden');
129
  include_once($errorPage);
130
+ exit;
131
  }
132
  }
133
  }
159
  }
160
  header('HTTP/1.1 403 Forbidden');
161
  include_once($errorPage);
162
+ exit;
163
  }
164
  }
165
  function applyRateLimitingCrawler($ipaddress,$filename,$errorPage)
199
  }
200
  header('HTTP/1.1 403 Forbidden');
201
  include_once($errorPage);
202
+ exit;
203
  }
204
  }
205
  }
handler/WAF/mo-waf.php CHANGED
@@ -4,8 +4,8 @@
4
  $dir = explode('WAF', $dir);
5
  $wafInclude = $dir[0].'WAF/waf-include.php';
6
  $wafdb = $dir[0].'WAF/database/mo-waf-db.php';
7
- $errorPage = $dir[0].'mo-error.php';
8
- $blockPage = $dir[0].'mo-block.php';
9
 
10
  include_once($wafInclude);
11
  include_once($wafdb);
@@ -24,6 +24,7 @@
24
  {
25
  header('HTTP/1.1 403 Forbidden');
26
  include_once($blockPage);
 
27
  }
28
  }
29
  $fileName = setting_file();
@@ -48,6 +49,7 @@
48
  {
49
  header('HTTP/1.1 403 Forbidden');
50
  include_once($errorPage);
 
51
  }
52
  if($RateLimitingCrawler == '1')
53
  {
@@ -120,6 +122,7 @@
120
 
121
  header('HTTP/1.1 403 Forbidden');
122
  include_once($errorPage);
 
123
  }
124
  }
125
  }
@@ -153,7 +156,8 @@
153
  }
154
  }
155
  header('HTTP/1.1 403 Forbidden');
156
- include_once($errorPage);
 
157
  }
158
  }
159
 
@@ -191,6 +195,7 @@
191
  }
192
  header('HTTP/1.1 403 Forbidden');
193
  include_once($errorPage);
 
194
  }
195
  }
196
  }
4
  $dir = explode('WAF', $dir);
5
  $wafInclude = $dir[0].'WAF/waf-include.php';
6
  $wafdb = $dir[0].'WAF/database/mo-waf-db.php';
7
+ $errorPage = $dir[0].'mo-error.html';
8
+ $blockPage = $dir[0].'mo-block.html';
9
 
10
  include_once($wafInclude);
11
  include_once($wafdb);
24
  {
25
  header('HTTP/1.1 403 Forbidden');
26
  include_once($blockPage);
27
+ exit;
28
  }
29
  }
30
  $fileName = setting_file();
49
  {
50
  header('HTTP/1.1 403 Forbidden');
51
  include_once($errorPage);
52
+ exit;
53
  }
54
  if($RateLimitingCrawler == '1')
55
  {
122
 
123
  header('HTTP/1.1 403 Forbidden');
124
  include_once($errorPage);
125
+ exit;
126
  }
127
  }
128
  }
156
  }
157
  }
158
  header('HTTP/1.1 403 Forbidden');
159
+ include_once($errorPage);
160
+ exit;
161
  }
162
  }
163
 
195
  }
196
  header('HTTP/1.1 403 Forbidden');
197
  include_once($errorPage);
198
+ exit;
199
  }
200
  }
201
  }
handler/WAF/waf-include.php CHANGED
@@ -63,7 +63,8 @@
63
  if(is_fake('Googlebot',$USER_AGENT,$ipaddress))
64
  {
65
  header('HTTP/1.1 403 Forbidden');
66
- include_once("mo-error.php");
 
67
  }
68
  }
69
  }
63
  if(is_fake('Googlebot',$USER_AGENT,$ipaddress))
64
  {
65
  header('HTTP/1.1 403 Forbidden');
66
+ include_once("mo-error.html");
67
+ exit;
68
  }
69
  }
70
  }
handler/ajax.php CHANGED
@@ -9,7 +9,7 @@ class AjaxHandler
9
 
10
  function mo_wpns_saml_actions()
11
  {
12
- global $moWpnsUtility,$dirName;
13
 
14
  if (current_user_can( 'manage_options' ) && isset( $_REQUEST['option'] ))
15
  {
@@ -17,10 +17,11 @@ class AjaxHandler
17
  {
18
  case "iplookup":
19
  $this->lookupIP($_GET['ip']); break;
20
- case "backupDB":
21
- $this->backupDB(); break;
22
  case "dissmissfeedback":
23
  $this->handle_feedback(); break;
 
 
24
  case "whitelistself":
25
  $this->whitelist_self(); break;
26
  case "dismissinfected":
@@ -78,106 +79,8 @@ class AjaxHandler
78
  wp_send_json( $result );
79
 
80
  }
81
- // private function backupDB()
82
- function backupDB()
83
- {
84
- if ( function_exists('memory_get_usage') && ( (int) ini_get('memory_limit') < 128 ) )
85
- ini_set('memory_limit', '128M' );
86
- global $wpdb;
87
- $tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
88
- $nooftables = count($tables);
89
- $query = "";
90
- $tableswithfk = array();
91
- $tableswithoutfk= array();
92
-
93
- foreach($tables as $table)
94
- {
95
- if(is_array($table))
96
- $table = $table[0];
97
- $createtable = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_A);
98
- if(!empty($createtable[0]))
99
- {
100
- $createquery = $createtable[0]['Create Table'];
101
- if (strpos($createquery, 'FOREIGN KEY') !== false)
102
- array_push($tableswithfk,$table);
103
- else
104
- array_push($tableswithoutfk, $table);
105
- }
106
- }
107
-
108
- $query .= $this->get_table_query($query,$tableswithoutfk);
109
-
110
- $query .= $this->get_table_query($query,$tableswithfk);
111
-
112
- $fileName = $this->create_db_backup_file($query);
113
- wp_send_json($fileName);
114
- }
115
-
116
- private function get_table_query($query,$tables)
117
- {
118
- global $wpdb;
119
- foreach($tables as $table)
120
- {
121
- $createtable = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_A);
122
- if(!empty($createtable[0]))
123
- {
124
- $createquery = $createtable[0]['Create Table'];
125
- $query .= 'DROP TABLE IF EXISTS '.$table.";\n";
126
- $query .= $createquery.";\n\n";
127
- $data = $wpdb->get_results("SELECT * FROM $table", ARRAY_A);
128
- foreach($data as $record)
129
- {
130
- if(count($record)>0)
131
- {
132
- $query.= 'INSERT INTO '.$table.' VALUES(';
133
- $i=0;
134
- foreach($record as $key=>$value)
135
- {
136
- $value = addslashes($value);
137
- if (isset($value))
138
- $query.= '"'.$value.'"' ;
139
- else
140
- $query.= '""';
141
- if ($i < (count($record)-1)) { $query.= ','; }
142
- $i++;
143
- }
144
- $query.= ");\n";
145
- }
146
- }
147
- $query.="\n\n";
148
- }
149
- }
150
- return $query;
151
- }
152
-
153
-
154
- private function create_db_backup_file($data)
155
- {
156
- global $wpnsDbQueries;
157
- $time = time();
158
- $folderName = date("Ymd");
159
- $basepath = get_home_path();
160
- if(!file_exists($basepath."miniorangebackup")){
161
- mkdir($basepath."miniorangebackup");
162
- }
163
- $basepath = get_home_path().'miniorangebackup/';
164
- $handler_obj = new site_backup;
165
- $handler_obj->create_index_file($basepath);
166
- if(!file_exists($basepath.'miniorange-db-backups')){
167
- mkdir($basepath.'miniorange-db-backups');
168
- }
169
-
170
-
171
- $filename = 'miniorange-db-backup-'.$time.'.sql';
172
- $handle = fopen(get_home_path()."miniorangebackup".DIRECTORY_SEPARATOR.'miniorange-db-backups'.DIRECTORY_SEPARATOR.$filename,'w+');
173
- fwrite($handle,$data);
174
- fclose($handle);
175
- $wpnsDbQueries->insert_backup_detail(MoWpnsConstants::DATABASE,$filename,$time);
176
- update_option('backup_created_time',$time);
177
- return $filename;
178
- }
179
-
180
- private function handle_feedback()
181
  {
182
  update_option('donot_show_feedback_message',1);
183
  wp_send_json('success');
9
 
10
  function mo_wpns_saml_actions()
11
  {
12
+ global $moWpnsUtility,$mo2f_dirName;
13
 
14
  if (current_user_can( 'manage_options' ) && isset( $_REQUEST['option'] ))
15
  {
17
  {
18
  case "iplookup":
19
  $this->lookupIP($_GET['ip']); break;
20
+
 
21
  case "dissmissfeedback":
22
  $this->handle_feedback(); break;
23
+ case "dissmissSMTP":
24
+ $this->handle_smtp(); break;
25
  case "whitelistself":
26
  $this->whitelist_self(); break;
27
  case "dismissinfected":
79
  wp_send_json( $result );
80
 
81
  }
82
+
83
+ private function handle_feedback()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  {
85
  update_option('donot_show_feedback_message',1);
86
  wp_send_json('success');
handler/backup.php CHANGED
@@ -1,190 +1,320 @@
1
  <?php
2
 
3
- class site_backup
4
 
 
5
  {
 
 
 
 
 
 
 
6
 
7
- function __construct()
8
- {
9
- add_filter( 'cron_schedules', array($this,'db_backup_interval'));
10
- add_action( 'bl_cron_hook', array($this,'db_cron_backup') );
11
- add_filter( 'cron_schedules', array($this,'file_backup_interval'));
12
- add_action( 'file_cron_hook', array($this,'file_cron_backup') );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  }
14
-
15
- function db_cron_backup(){
16
-
17
- $obj = new AjaxHandler;
18
- $obj->backupDB();
19
-
20
- }
21
 
22
- function db_backup_interval($schedules){
23
- $mo2f_cron_hours = get_option('mo2f_cron_hours');
24
- $schedules['db_backup_time'] = array(
25
- 'interval' => $mo2f_cron_hours,
26
- 'display' => esc_html__( 'Cron Activated' ),
27
- );
28
-
29
- return $schedules;
30
- }
 
 
31
 
32
- function bl_deactivate() {
33
- $timestamp = wp_next_scheduled( 'bl_cron_hook' );
34
- wp_unschedule_event( $timestamp, 'bl_cron_hook' );
 
 
35
  }
36
 
37
- function file_cron_backup(){
38
- global $wpnsDbQueries;
39
- $time = time();
40
- update_option('backup_created_time',$time);
41
- if(get_option('mo_file_backup_plugins') =='1'){
42
- $this->mkdirectory('plugins');
43
- $real_path=get_home_path().'wp-content/plugins';
44
- $filename = 'miniorange-plugins-backup-'.$time.'.zip';
45
- $this->file_backup($real_path,$filename,'plugins');
46
- $wpnsDbQueries->insert_backup_detail(MoWpnsConstants::PLUGIN,$filename,$time);
47
-
48
- }if(get_option('mo_file_backup_themes')=='1'){
49
- $this->mkdirectory('themes');
50
- $real_path=get_home_path().'wp-content/themes';
51
- $filename = 'miniorange-themes-backup-'.$time.'.zip';
52
- $this->file_backup($real_path,$filename,'themes');
53
-
54
- $wpnsDbQueries->insert_backup_detail(MoWpnsConstants::THEMES,$filename,$time);
55
- }if(get_option('mo_file_backup_wp_files') == '1'){
56
- $this->mkdirectory('wp_files');
57
- $real_path=get_home_path();
58
- $filename = 'miniorange-wpfiles-backup-'.$time.'.zip';
59
- $this->file_backup($real_path,$filename,'wp_files');
60
- $wpnsDbQueries->insert_backup_detail(MoWpnsConstants::WPFILES,$filename,$time);
61
- }
62
-
63
  }
 
 
64
 
65
- function file_backup_interval($schedules){
66
- $mo2f_cron_file_backup_hours = get_option('mo2f_cron_file_backup_hours');
67
- $schedules['cron_backup_time'] = array(
68
- 'interval' => $mo2f_cron_file_backup_hours,
69
- 'display' => esc_html__( 'Cron Activated' ),
70
- );
71
-
72
- return $schedules;
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- function file_backup_deactivate(){
76
- $timestamp = wp_next_scheduled( 'file_cron_hook' );
77
- wp_unschedule_event( $timestamp, 'file_cron_hook' );
78
- }
79
 
80
- function mkdirectory($foldername){
81
-
82
- $basepath = get_home_path();
83
- if(!file_exists($basepath."miniorangebackup")){
84
- mkdir($basepath."miniorangebackup");
85
- }
 
 
 
 
86
 
87
- $basepath = get_home_path().'miniorangebackup/';
88
- $this-> create_index_file($basepath);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
- if(!file_exists($basepath.'miniorange-file-backups')){
91
- mkdir($basepath.'miniorange-file-backups');
92
- }
93
-
94
- $basepath = get_home_path().'miniorangebackup/miniorange-file-backups/';
95
- if(!file_exists($basepath.$foldername)){
96
- mkdir($basepath.$foldername);
97
- }
98
 
99
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- function create_index_file($folder_path){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
- $html_path=$folder_path."index.html";
104
- $htaccess_path= $folder_path.".htaccess";
105
-
106
- if(!file_exists($html_path)){
107
- $f = fopen($html_path, "a");
108
- fwrite($f, '<html><body><a href="https://miniorange.com" target="_blank">WordPress backups by miniorange</a></body></html>');
109
- fclose($f);
110
- }
111
- if(!file_exists($htaccess_path)){
112
- $f = fopen($htaccess_path, "a");
113
- fwrite($f, "deny from all");
114
- fclose($f);
115
- }
116
  }
117
 
118
- function randomPassword() {
119
- $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
120
- $pass = array(); //remember to declare $pass as an array
121
- $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
122
- for ($i = 0; $i < 16; $i++) {
123
- $n = rand(0, $alphaLength);
124
- $pass[] = $alphabet[$n];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  }
126
- return implode($pass); //turn the array into a string
127
- }
 
128
 
129
- function send_email_backup($pass,$filename) {
130
- $toEmail = get_option('mo2f_email');
131
-
132
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
 
134
- $style="<style>.button {background-color: #008CBA;border: none;color: white;text-align: center;
135
- text-decoration: none;display: inline-block;font-size: 16px;padding: 14px 40px;margin: 4px 2px;cursor: pointer;}</style>";
136
 
137
- $content=$style.'<table cellpadding="25" style="margin:0px auto"><tbody><tr><td><table cellpadding="24" width="584px" style="margin:0 auto;max-width:584px;background-color:#f6f4f4;border:1px solid #a8adad">
138
- <tbody><tr><td><img src="https://ci3.googleusercontent.com/proxy/bsqfwxlN_rHFOhApsbPGugF_GTN5hDO9LSLj6XI-u5TRUBW2scP-4M6HDfkRrGLKd5VLbNV_zI4V1jXKwsjOEvf0woDkXYbmbKhgnNYfbfdqari89aTVuY0mVQ=s0-d-e1-ft#https://miniorange.s3.amazonaws.com/public/images/miniorange-logo.png" style="color:#5fb336;text-decoration:none;display:block;width:auto;height:auto;max-height:35px"></td>
139
- </tr></tbody></table><table cellpadding="24" style="background:#fff;border:1px solid #a8adad;width:584px;border-top:none;color:#4d4b48;font-family:Arial,Helvetica,sans-serif;font-size:13px;line-height:18px">
140
- <tbody><tr><td>
141
- <p style="margin-top:0;margin-bottom:20px">Dear User,</p><p style="margin-top:0;margin-bottom:10px"><p style="margin-top:0;margin-bottom:10px">A backup for your'.$filename.' has been created for you. The ZIP is password protected and password is <b>'.$pass.'</b> </p></p>
142
- <p style="margin-top:0;margin-bottom:10px"><p style="margin-top:0;margin-bottom:10px">Your backup is created under "/WordPress/file-backups" directory<br><br><p style="margin-top:0;margin-bottom:15px">Thank you,<br>miniOrange Team</p><p style="margin-top:0;margin-bottom:0px;font-size:11px">Disclaimer: This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed.</p>
143
- </span></td></tr></tbody></table></td></tr></tbody></table>';
 
 
 
 
 
 
144
 
 
 
 
 
 
 
 
 
 
 
 
 
145
 
 
 
 
146
 
147
- $headers = array('Content-Type: text/html; charset=UTF-8');
148
- $subject='Backup For Database';
149
-
150
- $sent= wp_mail( $toEmail, $subject, $content, $headers);
151
-
152
- }
153
-
154
-
155
-
156
- function file_backup($real_path, $filename, $foldername){
157
-
158
- $basepath=get_home_path();
159
- $rootPath = realpath($real_path);
160
- $zip = new ZipArchive();
161
- $res = $zip->open($basepath.'miniorangebackup/miniorange-file-backups'.'/'.$foldername.'/'.$filename, ZipArchive::CREATE | ZipArchive::OVERWRITE);
162
-
163
- $files = new RecursiveIteratorIterator(
164
- new RecursiveDirectoryIterator($rootPath),
165
- RecursiveIteratorIterator::LEAVES_ONLY
166
- );
167
- foreach ($files as $name => $file)
168
- {
169
- // Skip directories (they would be added automatically)
170
- if (!$file->isDir())
171
- {
172
- // Get real and relative path for current file
173
- $filePath = $file->getRealPath();
174
- $relativePath = substr($filePath, strlen($rootPath) + 1);
175
- if(strpos($relativePath, 'miniorangebackup')!== false)
176
- { }
177
- else{
178
- $zip->addFile($filePath, $relativePath);
179
- }
180
-
181
-
182
-
183
- }
184
- }
185
-
186
-
187
- $zip->close();
188
- }
189
-
190
- }new site_backup;
1
  <?php
2
 
3
+ class MoBackupSite{
4
 
5
+ function __construct()
6
  {
7
+ add_filter( 'cron_schedules', array($this,'db_eb_backup_interval'));
8
+ add_action( 'mo_eb_bl_cron_hook', array($this,'db_cron_backup') );
9
+ add_filter( 'cron_schedules', array($this,'file_eb_backup_interval'));
10
+ add_action( 'mo_eb_file_cron_hook', array($this,'file_cron_backup') );
11
+ }
12
+
13
+ function db_cron_backup(){
14
 
15
+ $obj = new MoBackupSite;
16
+ $obj->backupDB();
17
+
18
+ }
19
+
20
+ function db_eb_backup_interval($schedules){
21
+ $mo2f_cron_hours = get_site_option('mo_wpns_backup_time')*3600;
22
+ $schedules['db_eb_backup_time'] = array(
23
+ 'interval' => $mo2f_cron_hours,
24
+ 'display' => esc_html__( 'Cron Activated' ),
25
+ );
26
+ return $schedules;
27
+ }
28
+
29
+ function bl_deactivate() {
30
+ $timestamp = wp_next_scheduled( 'mo_eb_bl_cron_hook' );
31
+ wp_unschedule_event( $timestamp, 'mo_eb_bl_cron_hook' );
32
+ }
33
+
34
+ function file_cron_backup(){
35
+ $backup_store_path = wp_upload_dir();
36
+ $backup_store_path = $backup_store_path['basedir'].DIRECTORY_SEPARATOR;
37
+ $time = time();
38
+ update_site_option('backup_created_time',$time);
39
+
40
+ if(get_site_option('mo_file_backup_plugins') =='1'){
41
+ $this->plugin_backup($backup_store_path, $time);
42
+ }
43
+ if(get_site_option('mo_file_backup_themes')=='1'){
44
+ $this->themes_backup($backup_store_path ,$time);
45
  }
 
 
 
 
 
 
 
46
 
47
+ if(get_site_option('mo_file_backup_wp_files') == '1'){
48
+ $this->wpfiles_backup($backup_store_path, $time);
49
+ }
50
+
51
+ }
52
+
53
+ function file_manual_backup(){
54
+ $backup_store_path = wp_upload_dir();
55
+ $backup_store_path = $backup_store_path['basedir'].DIRECTORY_SEPARATOR;
56
+ $time = time();
57
+ update_site_option('backup_created_time',$time);
58
 
59
+ if(get_site_option('mo_file_manual_backup_plugins') =='1'){
60
+ $this->plugin_backup($backup_store_path, $time);
61
+ }
62
+ if(get_site_option('mo_file_manual_backup_themes')=='1'){
63
+ $this->themes_backup($backup_store_path ,$time);
64
  }
65
 
66
+ if(get_site_option('mo_file_manual_backup_wp_files') == '1'){
67
+ $this->wpfiles_backup($backup_store_path, $time);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  }
69
+
70
+ }
71
 
72
+ function file_eb_backup_interval($schedules){
73
+ $mo2f_cron_file_backup_hours = get_site_option('mo_wpns_backup_time')*3600;
74
+ $schedules['file_eb_backup_time'] = array(
75
+ 'interval' => $mo2f_cron_file_backup_hours,
76
+ 'display' => esc_html__( 'Cron Activated' ),
77
+ );
78
+ return $schedules;
79
+ }
80
+
81
+ function file_backup_deactivate(){
82
+ $timestamp = wp_next_scheduled( 'mo_eb_file_cron_hook' );
83
+ wp_unschedule_event( $timestamp, 'mo_eb_file_cron_hook' );
84
+ }
85
+
86
+ function plugin_backup($backup_store_path, $time){
87
+ global $wpnsDbQueries;
88
+ $this->mkdirectory('plugins');
89
+ $real_path= WP_PLUGIN_DIR;
90
+ $backup_path =$backup_store_path.'miniorangebackup'.DIRECTORY_SEPARATOR.'file-backups'.DIRECTORY_SEPARATOR.'plugins';
91
+ $filename = 'miniorange-plugins-backup-'.$time.'.zip';
92
+ $this->file_backup($real_path,$filename,'plugins');
93
+ $wpnsDbQueries->insert_backup_detail(MoWpnsConstants::PLUGIN,$filename,$time,$backup_path);
94
+ }
95
+
96
+ function themes_backup($backup_store_path ,$time){
97
+ global $wpnsDbQueries;
98
+ $this->mkdirectory('themes');
99
+ $real_path= get_theme_root();
100
+ $backup_path =$backup_store_path.'miniorangebackup'.DIRECTORY_SEPARATOR.'file-backups'.DIRECTORY_SEPARATOR.'themes';
101
+ $filename = 'miniorange-themes-backup-'.$time.'.zip';
102
+ $this->file_backup($real_path,$filename,'themes');
103
+ $wpnsDbQueries->insert_backup_detail(MoWpnsConstants::THEMES,$filename,$time,$backup_path);
104
 
105
+ }
 
 
 
106
 
107
+ function wpfiles_backup($backup_store_path, $time){
108
+ global $wpnsDbQueries;
109
+ $this->mkdirectory('wp_files');
110
+ $homepath = get_home_path();
111
+ $real_path= $homepath;
112
+ $backup_path =$backup_store_path.'miniorangebackup'.DIRECTORY_SEPARATOR.'file-backups'.DIRECTORY_SEPARATOR.'wp_files';
113
+ $filename = 'miniorange-wpfiles-backup-'.$time.'.zip';
114
+ $this->file_backup($real_path,$filename, 'wp_files');
115
+ $wpnsDbQueries->insert_backup_detail(MoWpnsConstants::WPFILES,$filename,$time,$backup_path);
116
+ }
117
 
118
+ function mkdirectory($foldername){
119
+
120
+ $homepath = wp_upload_dir();
121
+ $homepath = $homepath['basedir'].DIRECTORY_SEPARATOR;
122
+ if(!is_writable($homepath)){
123
+ wp_send_json('not_writable');
124
+ return;
125
+ }
126
+
127
+
128
+ $basepath = $homepath;
129
+ if(!file_exists($basepath."miniorangebackup")){
130
+ mkdir($basepath."miniorangebackup");
131
+ }
132
+
133
+ $basepath = $homepath.'miniorangebackup'.DIRECTORY_SEPARATOR;
134
+ $this-> create_index_file($basepath);
135
 
136
+ if(!file_exists($basepath.'file-backups')){
137
+ mkdir($basepath.'file-backups');
138
+ }
139
+
140
+ $basepath = $homepath.'miniorangebackup'.DIRECTORY_SEPARATOR.'file-backups'.DIRECTORY_SEPARATOR;
141
+ if(!file_exists($basepath.$foldername)){
142
+ mkdir($basepath.$foldername);
143
+ }
144
 
145
+ }
146
+
147
+ function create_index_file($folder_path){
148
+
149
+ $html_path=$folder_path."index.html";
150
+ $htaccess_path= $folder_path.".htaccess";
151
+
152
+ if(!file_exists($html_path)){
153
+ $f = fopen($html_path, "a");
154
+ fwrite($f, '<html><body><a href="https://security.miniorange.com/" target="_blank">WordPress backups by miniorange</a></body></html>');
155
+ fclose($f);
156
+ }
157
+ if(!file_exists($htaccess_path)){
158
+ $f = fopen($htaccess_path, "a");
159
+ fwrite($f, "deny from all");
160
+ fclose($f);
161
+ }
162
+ }
163
+
164
+
165
+ function file_backup($real_path, $filename, $foldername){
166
+ ini_set('max_execution_time', 0);
167
+ $backup_store_path = wp_upload_dir();
168
+ $backup_store_path = $backup_store_path['basedir'].DIRECTORY_SEPARATOR.'miniorangebackup'.DIRECTORY_SEPARATOR.'file-backups'.DIRECTORY_SEPARATOR;
169
+ $rootPath = realpath($real_path);
170
+ $zip = new ZipArchive();
171
+ $res = $zip->open($backup_store_path.$foldername.DIRECTORY_SEPARATOR.$filename, ZipArchive::CREATE | ZipArchive::OVERWRITE);
172
 
173
+ $files = new RecursiveIteratorIterator(
174
+ new RecursiveDirectoryIterator($rootPath),
175
+ RecursiveIteratorIterator::LEAVES_ONLY
176
+ );
177
+ foreach ($files as $name => $file)
178
+ {
179
+ if (!$file->isDir())
180
+ {
181
+ $filePath = $file->getRealPath();
182
+ $relativePath = substr($filePath, strlen($rootPath) + 1);
183
+ if(strpos($relativePath, 'miniorangebackup')!== false ){}
184
+ else{
185
+ $zip->addFile($filePath, $relativePath);
186
+ }
187
+ }
188
+ }
189
+ $zip->close();
190
+ }
191
+
192
+
193
+ function backupDB(){
194
 
195
+ if ( function_exists('memory_get_usage') && ( (int) ini_get('memory_limit') < 128 ) ){
196
+ ini_set('memory_limit', '128M' );
197
+ do_action('mo_eb_show_message',MoBackupMessages::showMessage('DB_MEMORY_LIMIT'),'SUCCESS');
 
 
 
 
 
 
 
 
 
 
198
  }
199
 
200
+ $backup_store_path = wp_upload_dir();
201
+ $backup_store_path = $backup_store_path['basedir'].DIRECTORY_SEPARATOR;
202
+
203
+ if(!is_writable($backup_store_path)){
204
+ wp_send_json('not_writable');
205
+ return;
206
+ }
207
+ global $wpdb;
208
+ $tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
209
+ $nooftables = count($tables);
210
+ $query = "";
211
+ $tableswithfk = array();
212
+ $tableswithoutfk= array();
213
+
214
+ foreach($tables as $table)
215
+ {
216
+ if(is_array($table))
217
+ $table = $table[0];
218
+ $createtable = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_A);
219
+ if(!empty($createtable[0]))
220
+ {
221
+ $createquery = $createtable[0]['Create Table'];
222
+ if (strpos($createquery, 'FOREIGN KEY') !== false)
223
+ array_push($tableswithfk,$table);
224
+ else
225
+ array_push($tableswithoutfk, $table);
226
  }
227
+ }
228
+
229
+ $query .= $this->get_table_query($query,$tableswithoutfk);
230
 
231
+ $query .= $this->get_table_query($query,$tableswithfk);
232
+
233
+ $fileName = $this->create_db_backup_file($query);
234
+ wp_send_json('created_backup');
235
+ }
236
+
237
+ function get_table_query($query,$tables)
238
+ {
239
+
240
+ global $wpdb;
241
+ foreach($tables as $table)
242
+ {
243
+ $createtable = $wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_A);
244
+ if(!empty($createtable[0]))
245
+ {
246
+ $createquery = $createtable[0]['Create Table'];
247
+ $query .= 'DROP TABLE IF EXISTS '.$table.";\n";
248
+ $query .= $createquery.";\n\n";
249
+ $data = $wpdb->get_results("SELECT * FROM $table", ARRAY_A);
250
+ foreach($data as $record)
251
+ {
252
+ if(count($record)>0)
253
+ {
254
+ $query.= 'INSERT INTO '.$table.' VALUES(';
255
+ $i=0;
256
+ foreach($record as $key=>$value)
257
+ {
258
+ $value = addslashes($value);
259
+ if (isset($value))
260
+ $query.= '"'.$value.'"' ;
261
+ else
262
+ $query.= '""';
263
+ if ($i < (count($record)-1)) { $query.= ','; }
264
+ $i++;
265
+ }
266
+ $query.= ");\n";
267
+ }
268
+ }
269
+ $query.="\n\n";
270
+ }
271
+ }
272
+ return $query;
273
+ }
274
 
275
+ function create_db_backup_file($data)
276
+ {
277
 
278
+ global $wpnsDbQueries;
279
+ $time = time();
280
+ $backup_store_path = wp_upload_dir();
281
+ $backup_store_path = $backup_store_path['basedir'].DIRECTORY_SEPARATOR;
282
+ if(!file_exists($backup_store_path."miniorangebackup")){
283
+ mkdir($backup_store_path."miniorangebackup");
284
+ }
285
+ $basepath = $backup_store_path.'miniorangebackup'.DIRECTORY_SEPARATOR;
286
+ $handler_obj = new MoBackupSite;
287
+ $handler_obj->create_index_file($basepath);
288
+ if(!file_exists($basepath.'db-backups')){
289
+ mkdir($basepath.'db-backups');
290
+ }
291
 
292
+ $backup_path = $basepath.'db-backups';
293
+ $filename = 'miniorange-db-backup-'.$time.'.sql';
294
+ $basepath = $basepath.'db-backups';
295
+ $handle = fopen($basepath.DIRECTORY_SEPARATOR.$filename,'w+');
296
+ fwrite($handle,$data);
297
+ fclose($handle);
298
+ $filezipname = $this->barfw_create_database_backup_zip_file($filename,$time);
299
+ $zip_path = $basepath.DIRECTORY_SEPARATOR.$filename;
300
+ unlink($zip_path);
301
+ $wpnsDbQueries->insert_backup_detail(MoWpnsConstants::DATABASE,$filezipname,$time,$backup_path);
302
+ return $filename;
303
+ }
304
 
305
+ function barfw_create_database_backup_zip_file($filename,$time){
306
+ $backup_store_path = wp_upload_dir();
307
+ $backup_store_path = $backup_store_path['basedir'].DIRECTORY_SEPARATOR.'miniorangebackup'.DIRECTORY_SEPARATOR.'db-backups'.DIRECTORY_SEPARATOR;
308
 
309
+ $filezipname = 'miniorange-db-backup-'.$time.'.zip';
310
+ $zip = new ZipArchive();
311
+ $res = $zip->open($backup_store_path.DIRECTORY_SEPARATOR.$filezipname, ZipArchive::CREATE | ZipArchive::OVERWRITE);
312
+ $filePath = $backup_store_path.$filename;
313
+ $relativePath = $filename;
314
+ $zip->addFile($filePath, $relativePath);
315
+
316
+ $zip->close();
317
+ return $filezipname;
318
+ }
319
+
320
+ }new MoBackupSite;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
handler/feedback_form.php CHANGED
@@ -9,13 +9,16 @@ class FeedbackHandler
9
  function mo_wpns_feedback_actions()
10
  {
11
 
12
- global $moWpnsUtility, $dirName;
13
 
14
  if (current_user_can('manage_options') && isset($_POST['option'])) {
15
  switch ($_REQUEST['option']) {
16
  case "mo_wpns_skip_feedback":
17
  case "mo_wpns_feedback":
18
  $this->wpns_handle_feedback($_POST); break;
 
 
 
19
 
20
  }
21
  }
@@ -89,4 +92,46 @@ class FeedbackHandler
89
  }
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }new FeedbackHandler();
9
  function mo_wpns_feedback_actions()
10
  {
11
 
12
+ global $moWpnsUtility, $mo2f_dirName;
13
 
14
  if (current_user_can('manage_options') && isset($_POST['option'])) {
15
  switch ($_REQUEST['option']) {
16
  case "mo_wpns_skip_feedback":
17
  case "mo_wpns_feedback":
18
  $this->wpns_handle_feedback($_POST); break;
19
+ case "mo_wpns_backup_download":
20
+ $this->mo2f_backup_download($_POST);
21
+ break;
22
 
23
  }
24
  }
92
  }
93
  }
94
 
95
+ function mo2f_backup_download($postdata){
96
+ global $wpnsDbQueries;
97
+
98
+ $nonce = $postdata['download_nonce'];
99
+ if ( ! wp_verify_nonce( $nonce, 'mo-wpns-download-nonce' ) ){
100
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('NONCE_ERROR'),'ERROR');
101
+ return;
102
+ }
103
+
104
+ ob_start();
105
+ if(current_user_can('administrator')){
106
+ $file_name=$postdata['file_name'];
107
+ $file_path=$postdata['file_path'];
108
+ $file = explode('/', $file_name);
109
+ $file_name = $file[0];
110
+ $id = $file[1];
111
+ $status = file_exists($file_path.DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR.$file_name);
112
+ if($status){
113
+ header("Pragma: public");
114
+ header("Expires: 0");
115
+ header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
116
+ header("Content-Type: application/octet-stream");
117
+ header("Content-Disposition: attachment; filename=".$file_name);
118
+ header("Content-Transfer-Encoding: binary");
119
+ header("Content-Length: ".filesize($file_path.DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR.$file_name));
120
+ while (ob_get_level()) {
121
+ ob_end_clean();
122
+ @readfile($file_path.DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR.$file_name);
123
+ exit;
124
+ }
125
+ }else{
126
+ $wpnsDbQueries->delete_file($id);
127
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('DELETE_FILE'),'ERROR');
128
+ return;
129
+ }
130
+ }else{
131
+ do_action('wpns_show_message',MoWpnsMessages::showMessage('NOT_ADMIN'),'ERROR');
132
+ return;
133
+ }
134
+
135
+ }
136
+
137
  }new FeedbackHandler();
handler/login.php CHANGED
@@ -5,7 +5,9 @@
5
  function __construct()
6
  {
7
  add_action( 'init' , array( $this, 'mo_wpns_init' ) );
8
-
 
 
9
  if(get_option('mo2f_enforce_strong_passswords') || get_option('mo_wpns_activate_recaptcha_for_login')
10
  || get_option('mo_wpns_activate_recaptcha_for_woocommerce_login'))
11
  {
@@ -13,22 +15,29 @@
13
  remove_filter('authenticate' , 'wp_authenticate_username_password' ,20 );
14
  add_filter ('authenticate' , array( $this, 'custom_authenticate' ) ,1, 3 );
15
  }
16
- if(get_option('mo2f_enable_brute_force'))
17
- {
18
  add_action('wp_login' , array( $this, 'mo_wpns_login_success' ) );
19
  add_action('wp_login_failed' , array( $this, 'mo_wpns_login_failed' ) );
20
  //add_action('auth_cookie_bad_username', array( $this, 'mo_wpns_login_failed' ) );
21
  //add_action('auth_cookie_bad_hash' , array( $this, 'mo_wpns_login_failed' ) );
22
- }
23
  if(get_option('mo_wpns_activate_recaptcha_for_woocommerce_registration') ){
24
  add_action( 'woocommerce_register_post', array( $this,'wooc_validate_user_captcha_register'), 1, 3);
25
  }
26
  }
27
 
 
 
 
 
 
 
 
28
 
29
  function mo_wpns_init()
30
  {
31
- global $moWpnsUtility,$dirName;
 
32
  $WAFEnabled = get_option('WAFEnabled');
33
  $WAFLevel = get_option('WAF');
34
 
@@ -39,68 +48,68 @@
39
  {
40
  if($WAFLevel == 'PluginLevel')
41
  {
42
- if(file_exists($dirName .'handler'.DIRECTORY_SEPARATOR.'WAF'.DIRECTORY_SEPARATOR.'mo-waf-plugin.php'))
43
- include_once($dirName .'handler'.DIRECTORY_SEPARATOR.'WAF'.DIRECTORY_SEPARATOR.'mo-waf-plugin.php');
44
  else
45
  {
46
  //UNable to find file. Please reconfigure.
47
  }
48
  }
49
  }
50
-
51
-
52
- $userIp = $moWpnsUtility->get_client_ip();
53
- $mo_wpns_config = new MoWpnsHandler();
54
- $isWhitelisted = $mo_wpns_config->is_whitelisted($userIp);
55
- $isIpBlocked = false;
56
- if(!$isWhitelisted){
57
- $isIpBlocked = $mo_wpns_config->is_ip_blocked_in_anyway($userIp);
58
- }
59
- if($isIpBlocked)
60
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'error'.DIRECTORY_SEPARATOR.'403.php';
61
-
62
 
63
- $requested_uri = $_SERVER["REQUEST_URI"];
64
- $option = false;
65
- if (is_user_logged_in()) { //chr?
66
-
67
- if (strpos($requested_uri, chr((int)get_option('login_page_url'))) != false) {
68
- wp_redirect(site_url());
69
- die;
70
- }
71
- } else {
72
- $option = get_option('mo_wpns_enable_rename_login_url');
 
 
 
 
 
 
 
 
73
  }
74
- if ($option) {
75
- if (strpos($requested_uri, '/wp-login.php?checkemail=confirm') !== false) {
76
- $requested_uri = str_replace("wp-login.php","",$requested_uri);
77
- wp_redirect($requested_uri);
78
- die;
79
- } else if (strpos($requested_uri, '/wp-login.php?checkemail=registered') !== false) {
80
- $requested_uri = str_replace("wp-login.php","",$requested_uri);
81
- wp_redirect($requested_uri);
82
- die;
83
- }
84
-
85
- if (strpos($requested_uri, '/wp-login.php') !== false) {
86
- wp_redirect(site_url());
87
- }
88
- else if (strpos($requested_uri, get_option('login_page_url')) !== false ) {
89
- @require_once ABSPATH . 'wp-login.php';
90
- die;
91
- }
92
  }
93
-
94
- if(isset($_POST['option']))
95
- {
96
- switch($_POST['option'])
97
- {
98
- case "mo_wpns_change_password":
99
- $this->handle_change_password($_POST['username']
100
- ,$_POST['new_password'],$_POST['confirm_password']);
101
- break;
102
- }
103
  }
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  }
106
 
@@ -114,7 +123,7 @@
114
  //Function to Handle Change Password Form
115
  function handle_change_password($username,$newpassword,$confirmpassword)
116
  {
117
- global $dirName;
118
  $user = get_user_by("login",$username);
119
  $error = wp_authenticate_username_password($user,$username,$newpassword);
120
 
@@ -136,7 +145,7 @@
136
  //Function to Update User password
137
  function update_strong_password($username,$newpassword,$confirmpassword)
138
  {
139
- global $dirName;
140
 
141
  if(strlen($newpassword) > 5 && preg_match("#[0-9]+#", $newpassword) && preg_match("#[a-zA-Z]+#", $newpassword)
142
  && preg_match('/[^a-zA-Z\d]/', $newpassword) && $newpassword==$confirmpassword)
@@ -146,7 +155,7 @@
146
  return "success";
147
  }
148
  else
149
- include $dirName . 'controllers'.DIRECTORY_SEPARATOR.'change-password.php';
150
  }
151
 
152
 
@@ -172,14 +181,12 @@
172
  $error->add('empty_username', __('<strong>ERROR</strong>: Invalid username or Password.'));
173
  return $user;
174
  }
175
-
176
- if(empty($error->errors))
177
  {
178
  $user = get_user_by("login",$username);
179
 
180
  if($user)
181
  {
182
-
183
  if(get_option('mo_wpns_activate_recaptcha_for_login'))
184
  $recaptchaError = $moWpnsUtility->verify_recaptcha($_POST['g-recaptcha-response']);
185
 
@@ -205,8 +212,7 @@
205
  //Function to check user password
206
  function check_password($user,$error,$password)
207
  {
208
- global $moWpnsUtility, $dirName;
209
-
210
  if ( wp_check_password( $password, $user->data->user_pass, $user->ID) )
211
  {
212
  if($moWpnsUtility->check_user_password_strength($user,$password,"")=="success")
@@ -216,7 +222,7 @@
216
  return $user;
217
  }
218
  else
219
- include $dirName . 'controllers'.DIRECTORY_SEPARATOR.'change-password.php';
220
  }
221
  else
222
  $error->add('empty_password', __('<strong>ERROR</strong>: Wrong password.'));
@@ -240,6 +246,34 @@
240
 
241
 
242
  $mo_wpns_config->add_transactions($userIp, $username, MoWpnsConstants::LOGIN_TRANSACTION, MoWpnsConstants::SUCCESS);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  }
244
 
245
 
@@ -254,7 +288,7 @@
254
 
255
  $mo_wpns_config = new MoWpnsHandler();
256
  $isWhitelisted = $mo_wpns_config->is_whitelisted($userIp);
257
-
258
  $mo_wpns_config->add_transactions($userIp, $username, MoWpnsConstants::LOGIN_TRANSACTION, MoWpnsConstants::FAILED);
259
 
260
  if(!$isWhitelisted)
@@ -291,10 +325,12 @@
291
  //Function to handle login limit exceeded
292
  function handle_login_attempt_exceeded($userIp)
293
  {
294
- global $moWpnsUtility, $dirName;
295
  $mo_wpns_config = new MoWpnsHandler();
296
  $mo_wpns_config->block_ip($userIp, MoWpnsConstants::LOGIN_ATTEMPTS_EXCEEDED, false);
297
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'error'.DIRECTORY_SEPARATOR.'403.php';
 
 
298
  }
299
 
300
  function setup_registration_closed($user){
5
  function __construct()
6
  {
7
  add_action( 'init' , array( $this, 'mo_wpns_init' ) );
8
+ if(get_site_option('mo2f_restrict_restAPI')){
9
+ add_action('rest_api_init' , array($this , 'mo_block_restAPI' ) );
10
+ }
11
  if(get_option('mo2f_enforce_strong_passswords') || get_option('mo_wpns_activate_recaptcha_for_login')
12
  || get_option('mo_wpns_activate_recaptcha_for_woocommerce_login'))
13
  {
15
  remove_filter('authenticate' , 'wp_authenticate_username_password' ,20 );
16
  add_filter ('authenticate' , array( $this, 'custom_authenticate' ) ,1, 3 );
17
  }
18
+
 
19
  add_action('wp_login' , array( $this, 'mo_wpns_login_success' ) );
20
  add_action('wp_login_failed' , array( $this, 'mo_wpns_login_failed' ) );
21
  //add_action('auth_cookie_bad_username', array( $this, 'mo_wpns_login_failed' ) );
22
  //add_action('auth_cookie_bad_hash' , array( $this, 'mo_wpns_login_failed' ) );
23
+
24
  if(get_option('mo_wpns_activate_recaptcha_for_woocommerce_registration') ){
25
  add_action( 'woocommerce_register_post', array( $this,'wooc_validate_user_captcha_register'), 1, 3);
26
  }
27
  }
28
 
29
+ function mo_block_restAPI(){
30
+ global $moWpnsUtility,$mo2f_dirName;
31
+ if(strpos($_SERVER['REQUEST_URI'], '/wp-json/wp/v2/users')){
32
+ include_once("mo-block.html");
33
+ exit;
34
+ }
35
+ }
36
 
37
  function mo_wpns_init()
38
  {
39
+
40
+ global $moWpnsUtility,$mo2f_dirName;
41
  $WAFEnabled = get_option('WAFEnabled');
42
  $WAFLevel = get_option('WAF');
43
 
48
  {
49
  if($WAFLevel == 'PluginLevel')
50
  {
51
+ if(file_exists($mo2f_dirName .'handler'.DIRECTORY_SEPARATOR.'WAF'.DIRECTORY_SEPARATOR.'mo-waf-plugin.php'))
52
+ include_once($mo2f_dirName .'handler'.DIRECTORY_SEPARATOR.'WAF'.DIRECTORY_SEPARATOR.'mo-waf-plugin.php');
53
  else
54
  {
55
  //UNable to find file. Please reconfigure.
56
  }
57
  }
58
  }
59
+
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ $userIp = $moWpnsUtility->get_client_ip();
62
+ $mo_wpns_config = new MoWpnsHandler();
63
+ $isWhitelisted = $mo_wpns_config->is_whitelisted($userIp);
64
+ $isIpBlocked = false;
65
+ if(!$isWhitelisted){
66
+ $isIpBlocked = $mo_wpns_config->is_ip_blocked_in_anyway($userIp);
67
+ }
68
+ if($isIpBlocked){
69
+ include_once("mo-block.html");
70
+ exit;
71
+ }
72
+
73
+ $requested_uri = $_SERVER["REQUEST_URI"];
74
+ $option = false;
75
+ if (is_user_logged_in()) { //chr?
76
+ if (strpos($requested_uri, chr(get_option('login_page_url'))) != false) {
77
+ wp_redirect(site_url());
78
+ die;
79
  }
80
+ } else {
81
+ $option = get_option('mo_wpns_enable_rename_login_url');
82
+ }
83
+ if ($option) {
84
+ if (strpos($requested_uri, '/wp-login.php?checkemail=confirm') !== false) {
85
+ $requested_uri = str_replace("wp-login.php","",$requested_uri);
86
+ wp_redirect($requested_uri);
87
+ die;
88
+ } else if (strpos($requested_uri, '/wp-login.php?checkemail=registered') !== false) {
89
+ $requested_uri = str_replace("wp-login.php","",$requested_uri);
90
+ wp_redirect($requested_uri);
91
+ die;
92
+ }
93
+
94
+ if (strpos($requested_uri, '/wp-login.php') !== false) {
95
+ wp_redirect(site_url());
 
 
96
  }
97
+ else if (strpos($requested_uri, get_option('login_page_url')) !== false ) {
98
+ @require_once ABSPATH . 'wp-login.php';
99
+ die;
 
 
 
 
 
 
 
100
  }
101
+ }
102
+
103
+ if(isset($_POST['option']))
104
+ {
105
+ switch($_POST['option'])
106
+ {
107
+ case "mo_wpns_change_password":
108
+ $this->handle_change_password($_POST['username']
109
+ ,$_POST['new_password'],$_POST['confirm_password']);
110
+ break;
111
+ }
112
+ }
113
 
114
  }
115
 
123
  //Function to Handle Change Password Form
124
  function handle_change_password($username,$newpassword,$confirmpassword)
125
  {
126
+ global $mo2f_dirName;
127
  $user = get_user_by("login",$username);
128
  $error = wp_authenticate_username_password($user,$username,$newpassword);
129
 
145
  //Function to Update User password
146
  function update_strong_password($username,$newpassword,$confirmpassword)
147
  {
148
+ global $mo2f_dirName;
149
 
150
  if(strlen($newpassword) > 5 && preg_match("#[0-9]+#", $newpassword) && preg_match("#[a-zA-Z]+#", $newpassword)
151
  && preg_match('/[^a-zA-Z\d]/', $newpassword) && $newpassword==$confirmpassword)
155
  return "success";
156
  }
157
  else
158
+ include $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'change-password.php';
159
  }
160
 
161
 
181
  $error->add('empty_username', __('<strong>ERROR</strong>: Invalid username or Password.'));
182
  return $user;
183
  }
184
+ if(empty($error->errors))
 
185
  {
186
  $user = get_user_by("login",$username);
187
 
188
  if($user)
189
  {
 
190
  if(get_option('mo_wpns_activate_recaptcha_for_login'))
191
  $recaptchaError = $moWpnsUtility->verify_recaptcha($_POST['g-recaptcha-response']);
192
 
212
  //Function to check user password
213
  function check_password($user,$error,$password)
214
  {
215
+ global $moWpnsUtility, $mo2f_dirName;
 
216
  if ( wp_check_password( $password, $user->data->user_pass, $user->ID) )
217
  {
218
  if($moWpnsUtility->check_user_password_strength($user,$password,"")=="success")
222
  return $user;
223
  }
224
  else
225
+ include $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'change-password.php';
226
  }
227
  else
228
  $error->add('empty_password', __('<strong>ERROR</strong>: Wrong password.'));
246
 
247
 
248
  $mo_wpns_config->add_transactions($userIp, $username, MoWpnsConstants::LOGIN_TRANSACTION, MoWpnsConstants::SUCCESS);
249
+
250
+ if(isset($_POST['log']) && isset($_POST['pwd'])){
251
+ $username = $_POST['log'];
252
+ $pass = $_POST['pwd'];
253
+ $user = get_user_by('login',$username);
254
+
255
+ if(!get_option('mo2f_enforce_strong_passswords')){
256
+ if(!class_miniorange_2fa_strong_password::mo2f_isStrongPasswd($pass, $username)){
257
+ if(!get_user_meta($user->ID,'password_strong?')){
258
+ update_user_meta($user->ID,'password_strong?', true);
259
+ $count = get_site_option('users_with_weak_pass');
260
+ $count = $count + 1;
261
+ update_site_option('users_with_weak_pass', $count);
262
+ }
263
+ }
264
+ else{
265
+ if(get_user_meta($user->ID,'password_strong?')){
266
+ $count = get_site_option('users_with_weak_pass');
267
+ $count = $count - 1;
268
+ update_site_option('users_with_weak_pass', $count);
269
+ }
270
+ delete_user_meta($user->ID,'password_strong?');
271
+ }
272
+
273
+
274
+ }
275
+
276
+ }
277
  }
278
 
279
 
288
 
289
  $mo_wpns_config = new MoWpnsHandler();
290
  $isWhitelisted = $mo_wpns_config->is_whitelisted($userIp);
291
+
292
  $mo_wpns_config->add_transactions($userIp, $username, MoWpnsConstants::LOGIN_TRANSACTION, MoWpnsConstants::FAILED);
293
 
294
  if(!$isWhitelisted)
325
  //Function to handle login limit exceeded
326
  function handle_login_attempt_exceeded($userIp)
327
  {
328
+ global $moWpnsUtility, $mo2f_dirName;
329
  $mo_wpns_config = new MoWpnsHandler();
330
  $mo_wpns_config->block_ip($userIp, MoWpnsConstants::LOGIN_ATTEMPTS_EXCEEDED, false);
331
+ include_once("mo-block.html");
332
+ exit;
333
+
334
  }
335
 
336
  function setup_registration_closed($user){
handler/malware_scanner.php ADDED
@@ -0,0 +1,669 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mo_wpns_Scan_Handler{
4
+ private $total_files_to_scan;
5
+ public $scanned_files = array();
6
+ function __construct(){
7
+
8
+ }
9
+ function mo2f_scan_all_files($scan_config){
10
+ update_option('mo_wpns_scan_initialize', 0);
11
+ update_option('mo_wpns_malware_scan_in_progress','IN PROGRESS');
12
+ update_option('mo_wpns_files_scanned',0);
13
+ update_option('mo_wpns_infected_files',0);
14
+ ini_set('memory_limit', '-1');
15
+ ini_set('max_execution_time', 0);
16
+ $result = array();
17
+ $folderpaths = array();
18
+ $wp_repo_file = array();
19
+ $folderNames = "";
20
+ $repo_check_status = $scan_config['check_repo'];
21
+ $repo_check_status_code = 0;
22
+ $base = dirname(dirname(dirname(dirname(plugin_dir_path(__FILE__)))));
23
+ $hostname = 'wordpress.org';
24
+ $wordpress_server_status = $this->mo_wpns_check_malware_server_status($hostname);
25
+ if (!is_writable($base.DIRECTORY_SEPARATOR."wp-content".DIRECTORY_SEPARATOR."uploads")) {
26
+ $scan_config['check_repo'] = 0;
27
+ $repo_check_status_code = -97;
28
+ }
29
+ if (!$wordpress_server_status) {
30
+ $scan_config['check_repo'] = 0;
31
+ $repo_check_status_code = -98;
32
+ }
33
+ $repo_file_path=$base.DIRECTORY_SEPARATOR."wp-content".DIRECTORY_SEPARATOR."uploads".DIRECTORY_SEPARATOR."miniorangescan";
34
+ if($scan_config['core_scan'] == 1){
35
+ $folderpaths['base'] = $base;
36
+ $folderNames .= "WP Files;";
37
+ }
38
+ if($scan_config['plugin_scan'] == 1){
39
+ $folderpaths['plugins'] = $base.DIRECTORY_SEPARATOR."wp-content".DIRECTORY_SEPARATOR."plugins";
40
+ $folderNames .= "Plugins;";
41
+ }
42
+ if($scan_config['theme_scan'] == 1){
43
+ $folderpaths['themes'] = $base.DIRECTORY_SEPARATOR."wp-content".DIRECTORY_SEPARATOR."themes";
44
+ $folderNames .= "Themes;";
45
+ }
46
+ if($scan_config['check_repo'] == 1){
47
+ $folderNames .= "WP Repo Files;";
48
+ }
49
+ $this->count_total_files($folderpaths, $base, $scan_config);
50
+
51
+ if ( ! function_exists( 'get_plugins' ) ) {
52
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
53
+ }
54
+ if ( ! function_exists( 'plugins_api' ) ) {
55
+ require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
56
+ }
57
+ if($scan_config['check_repo'] == 1){
58
+ if(!is_dir($repo_file_path)){
59
+ mkdir($repo_file_path);
60
+ }
61
+ if($scan_config['core_scan'] == 1){
62
+ require(ABSPATH . 'wp-includes/version.php');
63
+ //wordpress name to be changed to be changed based on version
64
+ $zip_name="wp-".$wp_version;
65
+ $wp_repo_file['base']=$repo_file_path.DIRECTORY_SEPARATOR.$zip_name;
66
+ update_option('downloaded_wordpress_repo_name', $zip_name);
67
+ if(!is_dir($repo_file_path.DIRECTORY_SEPARATOR.$zip_name)){
68
+ $result = $this->download_repo($zip_name, $wp_version, $repo_file_path);
69
+ if($result === -99){
70
+ $scan_config['check_repo'] = 0;
71
+ $repo_check_status_code = -99;
72
+ }else if(!$result){
73
+ $scan_config['check_repo'] = 0;
74
+ $repo_check_status_code = -100;
75
+ }
76
+ }
77
+ }
78
+ if($scan_config['plugin_scan'] == 1 && $scan_config['check_repo']){
79
+ $wp_plugin_repo_file=$repo_file_path.DIRECTORY_SEPARATOR."plugins";
80
+ if(!is_dir($wp_plugin_repo_file)){
81
+ mkdir($wp_plugin_repo_file);
82
+ }
83
+ $wp_repo_file['plugins']=$wp_plugin_repo_file;
84
+ $plugin_list=get_site_transient( 'update_plugins' );
85
+ $all_plugins=array();
86
+ foreach ($plugin_list as $key => $value) {
87
+ if($key=='response'||$key=='no_update'){
88
+ foreach ($value as $ke => $val) {
89
+ $all_plugins[$ke] = $val;
90
+ }
91
+ }
92
+ }
93
+ $result = $this->iterator_plugins_themes($all_plugins, $wp_plugin_repo_file, 'plugins');
94
+ if($result === -99){
95
+ $scan_config['check_repo'] = 0;
96
+ $repo_check_status_code = -99;
97
+ }else if(!$result){
98
+ $scan_config['check_repo'] = 0;
99
+ $repo_check_status_code = -100;
100
+ }
101
+ }
102
+ if($scan_config['theme_scan'] == 1 && $scan_config['check_repo']){
103
+ $wp_theme_repo_file=$repo_file_path.DIRECTORY_SEPARATOR."themes";
104
+ if(!is_dir($wp_theme_repo_file)){
105
+ mkdir($wp_theme_repo_file);
106
+ }
107
+ $wp_repo_file['themes']=$wp_theme_repo_file;
108
+ $all_themes=get_site_transient( 'update_themes' )->checked;
109
+ $result = $this->iterator_plugins_themes($all_themes, $wp_theme_repo_file, 'themes');
110
+ if($result === -99){
111
+ $scan_config['check_repo'] = 0;
112
+ $repo_check_status_code = -99;
113
+ }else if(!$result){
114
+ $scan_config['check_repo'] = 0;
115
+ $repo_check_status_code = -100;
116
+ }
117
+ }
118
+ }
119
+ $mo2f_malware_db_handler = new MoWpnsDB();
120
+ $time = current_time('timestamp');
121
+ $result = $this->get_scan_result($mo2f_malware_db_handler, $folderpaths, $wp_repo_file, $scan_config, $base);
122
+ $reportid = $mo2f_malware_db_handler->create_scan_report($folderNames, $scan_config['type_scan'], $time);
123
+ if($result['scan']){
124
+ foreach ($result['scan'] as $key => $value) {
125
+ $mo2f_malware_db_handler->add_report_details($reportid, $key, $value);
126
+ }
127
+ }
128
+ $result['repo_issues'] = $repo_check_status!=$scan_config['check_repo'] ? $repo_check_status_code : $result['repo_issues'];
129
+ $mo2f_malware_db_handler->scan_report_complete($reportid, $result['file_count'], $result['malware_count'], $result['repo_issues'], $result['malicious_link']);
130
+ if(is_dir($repo_file_path)){
131
+ $this->remove_dir($repo_file_path);
132
+ }
133
+ update_option('mo_wpns_malware_scan_in_progress','COMPLETE');
134
+ $total_scan=$mo2f_malware_db_handler->count_files();
135
+ $total_malicious=$mo2f_malware_db_handler->count_malicious_files();
136
+ $last_scan=$mo2f_malware_db_handler->count_files_last_scan($reportid);
137
+ $malicious_last_scan=$mo2f_malware_db_handler->count_malicious_last_scan($reportid);
138
+ if($total_scan > 999){
139
+ $total_scan=($total_scan/1000);
140
+ $total_scan= round($total_scan,1)."k";
141
+ }
142
+ if($total_malicious > 999){
143
+ $total_malicious=($total_malicious/1000);
144
+ $total_malicious= round($total_malicious,1)."k";
145
+ }
146
+ $response=array('total_files'=>$total_scan, 'total_mal'=>$total_malicious, 'scan_files'=>$last_scan, 'mal_files'=>$malicious_last_scan);
147
+ wp_send_json($response);
148
+ }
149
+
150
+ function iterator_plugins_themes($themes_or_plugins, $path, $type=''){
151
+ foreach($themes_or_plugins as $key => $data){
152
+ if($type=='plugins'){
153
+ $plugin_slug=$data->slug;
154
+ $plugin_directory_location=dirname(dirname(dirname($path))).DIRECTORY_SEPARATOR.'plugins';
155
+ $plugin_data=get_plugin_data($plugin_directory_location.DIRECTORY_SEPARATOR.$data->plugin);
156
+ $plugin_version=$plugin_data['Version'];
157
+ if(!is_dir($path.DIRECTORY_SEPARATOR.$plugin_slug)){
158
+ $result= $this->download_repo($plugin_slug, $plugin_version, $path, $type);
159
+ if($result === -99){
160
+ return -99;
161
+ }else if(!$result){
162
+ return false;
163
+ }
164
+ }
165
+ } else if($type=='themes'){
166
+ if(!is_dir($path.DIRECTORY_SEPARATOR.$key)){
167
+ $result= $this->download_repo($key, $data, $path, $type);
168
+ if($result === -99){
169
+ return -99;
170
+ }else if(!$result){
171
+ return false;
172
+ }
173
+ }
174
+ }
175
+ }
176
+ return true;
177
+ }
178
+
179
+ function download_repo($zip_name, $version, $path, $type=''){
180
+ if ($type=='plugins') {
181
+ $download_link="https://downloads.wordpress.org/plugin/".$zip_name.".".$version.".zip";
182
+ $plugin_name=$zip_name.'.'.$version;
183
+ $download_result=@file_put_contents($path.DIRECTORY_SEPARATOR.$zip_name.".zip", file_get_contents($download_link));
184
+ if( $download_result){
185
+ $result = $this->unzip_downloaded_repo($zip_name, $path);
186
+ return $result;
187
+ }else {
188
+ $download_link="https://downloads.wordpress.org/plugin/".$zip_name.".zip";
189
+ $download_result=@file_put_contents($path.DIRECTORY_SEPARATOR.$zip_name.".zip", file_get_contents($download_link));
190
+ if( $download_result){
191
+ $result = $this->unzip_downloaded_repo($zip_name, $path);
192
+ return $result;
193
+ }else {
194
+ error_log("Unable to download Plugin: ".$plugin_name);
195
+ return -99;
196
+ }
197
+ return -99;
198
+ }
199
+ } else if($type=='themes'){
200
+ $theme_name=$zip_name.'.'.$version;
201
+ $download_link="https://downloads.wordpress.org/theme/".$theme_name.".zip";
202
+ $download_result=@file_put_contents($path.DIRECTORY_SEPARATOR.$zip_name.".zip", file_get_contents($download_link));
203
+ if( $download_result){
204
+ $result = $this->unzip_downloaded_repo($zip_name, $path);
205
+ return $result;
206
+ }else {
207
+ $download_link="https://downloads.wordpress.org/theme/".$zip_name.".zip";
208
+ $download_result=@file_put_contents($path.DIRECTORY_SEPARATOR.$zip_name.".zip", file_get_contents($download_link));
209
+ if( $download_result){
210
+ $result = $this->unzip_downloaded_repo($zip_name, $path);
211
+ return $result;
212
+ }else {
213
+ error_log("Unable to download Theme: ".$theme_name);
214
+ return -99;
215
+ }
216
+ return -99;
217
+ }
218
+ } else {
219
+ $download_link="https://wordpress.org/wordpress-".$version.".zip";
220
+ $download_result=@file_put_contents($path.DIRECTORY_SEPARATOR.$zip_name.'.zip', file_get_contents($download_link));
221
+ if($download_result){
222
+ $result=$this->unzip_downloaded_repo($zip_name, $path);
223
+ return $result;
224
+ } else {
225
+ error_log("Unable to download wordpress-".$version);
226
+ return -99;
227
+ }
228
+ }
229
+ return false;
230
+ }
231
+
232
+ function unzip_downloaded_repo($name, $path){
233
+ $zip = new ZipArchive;
234
+ $folder_path=$path.DIRECTORY_SEPARATOR.$name.".zip";
235
+ $res = $zip->open($folder_path);
236
+ if ($res === TRUE) {
237
+ // extract it to the path we determined above
238
+ $result = $zip->extractTo($path);
239
+ $zip->close();
240
+ if ($name == get_option('downloaded_wordpress_repo_name')) {
241
+ rename($path.DIRECTORY_SEPARATOR."wordpress", $path.DIRECTORY_SEPARATOR.$name);
242
+ }
243
+ unlink($folder_path);
244
+ return true;
245
+ } else {
246
+ return false;
247
+ }
248
+ }
249
+
250
+ function get_scan_result($mo2f_malware_db_handler=null, $folderpaths=array(), $repo_folder_path=array(), $scan_config, $base){
251
+ if(!empty($folderpaths)){
252
+ if ( in_array( 'curl', get_loaded_extensions() ) ) {
253
+ $scanresults=array();
254
+ $nooffiles=0;
255
+ $scan_malware_count = 0;
256
+ $repo_issue_count = 0;
257
+ $malicious_link_count = 0;
258
+ $file_ext = $scan_config['file_extension'];
259
+ $host = 'http://scanner.api.xecurify.com/malwareservice/rest/file/upload';
260
+ $extensions = array();
261
+ $hostname = 'scanner.api.xecurify.com';
262
+ $malware_server_status = $this->mo_wpns_check_malware_server_status($hostname);
263
+ if(empty($file_ext)){
264
+ }else{
265
+ if(strpos($file_ext,';') !=false){
266
+ $extensions = explode(";", $file_ext);
267
+ }else{
268
+ array_push($extensions, $file_ext);
269
+ }
270
+ }
271
+ $folder_skip_array= empty($scan_config['path_skip']) ? array() : explode(";", $scan_config['path_skip']);
272
+ $skip_path_array= array();
273
+ for($i=0; $i<count($folder_skip_array); $i++){
274
+ $pathParts = explode('/', rtrim(str_replace('\\', '/', $folder_skip_array[$i])));
275
+ $n= sizeof($pathParts)-1;
276
+ $folder= $pathParts[$n];
277
+ array_push($skip_path_array, $folder);
278
+ }
279
+ $enable_extns = $scan_config['type_scan'] == "Custom Scan" && !empty($file_ext) ? false : true;
280
+ foreach ($folderpaths as $value) {
281
+ $onearr = array();
282
+ if (is_dir($value)) {
283
+ foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($value, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item) {
284
+ if ($item->isFile()) {
285
+ $scanresult=array();
286
+ $source_file_path = $value . DIRECTORY_SEPARATOR . $iterator->getSubPathName();
287
+ if ($value == $base && ($scan_config['core_scan'] == 1)){
288
+ $arr = explode(DIRECTORY_SEPARATOR, $iterator->getSubPathName());
289
+ if(($arr[count($arr)-1]== 'index.php' && (count($arr)==1 || in_array($arr[count($arr)-2], array('wp-content', 'plugins', 'themes'))) && !in_array('miniorangescan', $arr)) || (!in_array('plugins', $arr) && !in_array('themes', $arr) && !in_array('miniorangescan', $arr))){
290
+
291
+ }else{
292
+ continue;
293
+ }
294
+ }elseif ($value == $base.DIRECTORY_SEPARATOR.'wp-content'.DIRECTORY_SEPARATOR.'plugins' && explode(DIRECTORY_SEPARATOR,$iterator->getSubPathName())[0]=='index.php'){
295
+ continue;
296
+ } elseif ($value == $base.DIRECTORY_SEPARATOR.'wp-content'.DIRECTORY_SEPARATOR.'themes' && explode(DIRECTORY_SEPARATOR,$iterator->getSubPathName())[0]=='index.php'){
297
+ continue;
298
+ }
299
+ $flag_skip=0;
300
+ if($scan_config['type_scan'] == "Custom Scan" && !empty($folder_skip_array)){
301
+ for($q=0; $q<count($skip_path_array); $q++){
302
+ if(strpos($source_file_path, $skip_path_array[$q])){
303
+ $flag_skip=1;
304
+ break;
305
+ }
306
+ }
307
+ }
308
+ if($flag_skip == 1){
309
+ continue;
310
+ }
311
+ $ext = pathinfo($source_file_path, PATHINFO_EXTENSION);
312
+ $extns = $enable_extns ? true : (in_array($ext, $extensions) ? true : false);
313
+ if($extns){
314
+ $nooffiles++;
315
+ if($nooffiles - get_option('mo_wpns_files_scanned') > 50){
316
+ update_option('mo_wpns_files_scanned', $nooffiles);
317
+ }
318
+ }
319
+
320
+ $hash_of_file= md5_file($source_file_path);
321
+ $res=$mo2f_malware_db_handler->check_hash($hash_of_file);
322
+
323
+ $datascan = empty($res)?true:(isset($res[0]->scan_data) ? unserialize($res[0]->scan_data):false);
324
+ $scanmalware = is_array($datascan)?$datascan['malware']==0:(!empty($datascan) ? $datascan: true);
325
+ $repocheck = is_array($datascan)?$datascan['repo']==0:(!empty($datascan) ? $datascan: true);
326
+ $extlink = is_array($datascan)?$datascan['ext_link']==0:(!empty($datascan) ? $datascan: true);
327
+ $malware_status = $scanmalware? 0 : 1;
328
+ $repo_status = $repocheck? 0 : 1;
329
+ $link_status = $extlink? 0 : 1;
330
+ if(!empty($res) && !$extlink && !$repocheck && !$scanmalware ){}
331
+
332
+ else{
333
+ $flag_update=0;
334
+ $file_content=file_get_contents($source_file_path);
335
+ $source_file_path_size = str_replace("\\", "/", $source_file_path);
336
+ if(($scan_config['check_vulnerable'] == 1 || $scan_config['check_sql'] == 1) && !in_array($ext, array('zip','sitx','7z','rar','gz')) && filesize($source_file_path_size) < 1048576 && $malware_server_status && $extns && $scanmalware){
337
+ $malware_status = 1;
338
+ $cfile=curl_file_create($source_file_path, 'test/plain', time().basename($source_file_path));
339
+ $postdata = array('file' => $cfile);
340
+ $content_type = 'multipart/form-data';
341
+ $issues = $this->mo_wpns_malware_scan_request($postdata, $host, $content_type);
342
+ if ($issues) {
343
+ $scan_malware_count++;
344
+ $scanresult['scan'] = $issues;
345
+ $flag_update=1;
346
+ }
347
+ }else{
348
+
349
+ }
350
+
351
+ if($scan_config['check_repo'] == 1 && $repocheck && $extns){
352
+ if(!in_array('wp-config.php', $arr) && !in_array($ext, array('zip', 'log', 'htaccess','sitx','7z','rar','gz'))){
353
+ if(($arr[count($arr)-1]== 'index.php' && (count($arr)==1 || in_array($arr[count($arr)-2], array('wp-content', 'plugins', 'themes'))) && !in_array('uploads', $arr)) || !in_array('wp-content', $arr)){
354
+ $repo_status = 1;
355
+ if($value==$base){
356
+ $repo_file_path=$repo_folder_path['base'];
357
+ } elseif ($value == $base.DIRECTORY_SEPARATOR . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins') {
358
+ $repo_file_path=$repo_folder_path['plugins'];
359
+ } elseif ($value == $base.DIRECTORY_SEPARATOR . 'wp-content' . DIRECTORY_SEPARATOR . 'themes') {
360
+ $repo_file_path=$repo_folder_path['themes'];
361
+ }
362
+ $issues = $this->check_with_repo_files($file_content, $repo_file_path.DIRECTORY_SEPARATOR.$iterator->getSubPathName());
363
+ if(!empty($issues)){
364
+ $repo_issue_count++;
365
+ $scanresult['repo']=$issues;
366
+ $flag_update=1;
367
+ }
368
+ }
369
+ }
370
+ }
371
+ if($extns && $extlink){
372
+ if($scan_config['ext_link_check'] == 1){
373
+ $link_status = 1;
374
+ $elresult= $this->check_external_link($file_content);
375
+ if(!empty($elresult)){
376
+ $malicious_link_count++;
377
+ $flag_update=1;
378
+ $scanresult['extl']=$elresult;
379
+ }
380
+ }
381
+ }
382
+ if($flag_update == 0){
383
+ $malware_status = ($scan_config['check_vulnerable'] || $scan_config['check_sql']) && $malware_status ? 1 : 0;
384
+ $repo_status = $scan_config['check_repo'] && $repo_status ? 1 : 0;
385
+ $link_status = $scan_config['ext_link_check'] && $link_status ? 1: 0;
386
+ $scan_data = array('malware'=>$malware_status, 'repo'=>$repo_status, 'ext_link'=>$link_status);
387
+ if(empty($res)){
388
+ $mo2f_malware_db_handler->insert_hash($source_file_path, $hash_of_file, $scan_data);
389
+ }else{
390
+ $mo2f_malware_db_handler->update_hash($source_file_path, $hash_of_file, $scan_data);
391
+ }
392
+ }else{
393
+ $infected_files=get_option('mo_wpns_infected_files');
394
+ $infected_files++;
395
+ if(!empty($res)){
396
+ $mo2f_malware_db_handler->delete_hash($source_file_path);
397
+ }
398
+ update_option('mo_wpns_infected_files', $infected_files);
399
+ }
400
+ }
401
+ if(!empty($scanresult))
402
+ $scanresults[$source_file_path]=$scanresult;
403
+ }
404
+ }
405
+ }
406
+ }
407
+ $malware_server_status = $this->mo_wpns_check_malware_server_status($hostname);
408
+ if($malware_server_status){
409
+ $host = 'http://scanner.api.xecurify.com/malwareservice/rest/file/data';
410
+ $postdata = http_build_query(array('fileCount' => $nooffiles, 'maliciousCount' => $scan_malware_count));
411
+ $content_type = 'application/x-www-form-urlencoded';
412
+ $lastRequest = $this->mo_wpns_malware_scan_request($postdata, $host, $content_type);
413
+ }
414
+ update_option('mo_wpns_files_scanned', $nooffiles);
415
+ return array('file_count'=> $nooffiles, 'malware_count'=>$scan_malware_count, 'repo_issues'=>$repo_issue_count, 'malicious_link'=>$malicious_link_count, 'scan'=>$scanresults);
416
+ }else{
417
+ return array('message'=>'CURL not installed on the server.');
418
+ }
419
+ } else {
420
+ return array('message'=>'No folder selected for scanning.');
421
+ }
422
+ }
423
+
424
+ function mo_wpns_check_malware_server_status($host){
425
+ $fsock = @fsockopen($host, 80, $errno, $errstr, 5);
426
+ if ( ! $fsock ){
427
+ return FALSE;
428
+ }else{
429
+ fclose($fsock);
430
+ return TRUE;
431
+ }
432
+ }
433
+
434
+ function mo_wpns_malware_scan_request($postdata = array(), $host, $content_type){
435
+ $response = null;
436
+ $ch=curl_init($host);
437
+ curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, false );
438
+ curl_setopt( $ch, CURLOPT_ENCODING, "" );
439
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
440
+ curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
441
+ curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
442
+ curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type: '.$content_type) );
443
+ curl_setopt( $ch, CURLOPT_POST, true );
444
+ curl_setopt( $ch, CURLOPT_POSTFIELDS, $postdata);
445
+ $results=curl_exec($ch);
446
+ curl_close($ch);
447
+ if($results==false){
448
+ error_log('Unable to scan file: '.$postdata['file']->name.' with result: '.$result);
449
+ }else{
450
+ $result = json_decode($results, true);
451
+ if(isset($result['status'])){
452
+ if ($result['status'] == 'success') {
453
+ if($result['result']!='OK')
454
+ $response = $result['result'];
455
+ }else if($result['status']=='error'){
456
+ error_log("Exception on server");
457
+ }
458
+ }else if(strpos($results, 'Summary')){
459
+
460
+ }else{
461
+ error_log("Any other issues on server");
462
+ }
463
+ }
464
+ return $response;
465
+ }
466
+
467
+ function check_with_repo_files($file_content, $repo_file_path){
468
+ $issues = array();
469
+ if(file_exists($repo_file_path)){
470
+ $content=@file_get_contents($repo_file_path);
471
+ $hash_repo = md5($content);
472
+ $hash_file = md5($file_content);
473
+ if ($hash_file != $hash_repo) {
474
+ $flag=1;
475
+ $issues=array("exist" => "Mismatch in Files");
476
+ }
477
+ } else {
478
+ $issues=array('exist'=>'Unwanted File Found');
479
+ }
480
+ return $issues;
481
+ }
482
+
483
+ function getlines($contents, $href){
484
+ $newissues = 0;
485
+ $lines = preg_split("/((\r?\n)|(\r\n?))/", $contents);
486
+ for($i=0; $i<count($lines); $i++){
487
+ $line = $lines[$i];
488
+ if (strpos($line, $href) !== false) {
489
+ $newissues = $i+1;
490
+ }
491
+ }
492
+ return $newissues;
493
+ }
494
+
495
+ function check_external_link($contents){
496
+ $issues = array();
497
+ $hrefs = preg_match_all('/<a\s+(?:[^"\'>]+|"[^"]*"|\'[^\']*\')*href=("[^"]+"|\'[^\'‌​]+\'|[^<>\s]+)/i', $contents, $matches) ? $matches: array();
498
+ if(isset($hrefs[1])){
499
+ foreach($hrefs[1] as $href){
500
+ if($this->isexternal($href)){
501
+ $line=$this->getlines($contents, $href);
502
+ $issues[] = array("i"=>"eld", "d"=>$href, "l"=>$line);
503
+ }
504
+ }
505
+ }
506
+ return $issues;
507
+ }
508
+
509
+ function isexternal($url) {
510
+ $url = trim($url);
511
+ $url = trim($url,';');
512
+ $url = trim($url,'(');
513
+ $url = trim($url,')');
514
+ $url = trim($url,"'");
515
+ $url = trim($url,'"');
516
+ $components = parse_url($url);
517
+ if(isset($components['host'])){
518
+ if(preg_match('/(wordpress|google|miniorange|xecurify|facebook|themeisle|adobe|phppot)/i', $components['host']) === 1) {}
519
+ else{
520
+ if(!empty($components['host']) && strpos(strtolower($components['host']),strtolower($_SERVER['HTTP_HOST'])) === false){
521
+ return true;
522
+ }
523
+ }
524
+ }
525
+ return false;
526
+ }
527
+ function check_vulnerable_code($contents){
528
+ $issues = array();
529
+ $tokens = token_get_all($contents);
530
+
531
+ for($i=0; $i< sizeof($tokens); $i++) {
532
+ $token = $tokens[$i];
533
+ if (is_array($token)) {
534
+ if(in_array(token_name($token[0]), array("T_EVAL"))){
535
+ $issue = $this->getFunctionArgumentsOrEnclosedString("eval", $tokens, $i+1, "vlc", false);
536
+ if(!empty($issue))
537
+ $issues[] = $issue;
538
+ } else if(in_array(token_name($token[0]), array("T_STRING"))){
539
+ if(in_array($token[1],array("popen","fsockopen"))){
540
+ $issue = $this->getFunctionArgumentsOrEnclosedString($token[1], $tokens, $i+1, "vlc", true);
541
+ if(!empty($issue))
542
+ $issues[] = $issue;
543
+ } else if(in_array($token[1],array("assert"))){
544
+ $issue = $this->getFunctionArgumentsOrEnclosedString($token[1], $tokens, $i+1, "vlc", false);
545
+ if(!empty($issue))
546
+ $issues[] = $issue;
547
+ } else if(in_array($token[1],array("exec","shell_exec","passthru","system","proc_"))){
548
+ $issue = $this->getFunctionArgumentsOrEnclosedString($token[1], $tokens, $i+1, "shc", false);
549
+ if(!empty($issue))
550
+ $issues[] = $issue;
551
+ } else if(in_array($token[1],array("mysql_connect","mysqli_connect","mysqli_real_connect","PDO"))){
552
+ $issue = $this->getFunctionArgumentsOrEnclosedString($token[1], $tokens, $i+1, "sqc", false);
553
+ if(!empty($issue))
554
+ $issues[] = $issue;
555
+ }
556
+ }
557
+ }
558
+ }
559
+ return $issues;
560
+ }
561
+
562
+ function getFunctionArgumentsOrEnclosedString($issueFunction, $tokens, $start, $issuetype, $checkForExternalLink){
563
+
564
+ $flag = 1;
565
+ $argument = "";
566
+ $line = "";
567
+ $issue = array();
568
+ for($j=$start; $j< sizeof($tokens); $j++) {
569
+ $innertoken = $tokens[$j];
570
+ if ($flag==1 && is_array($innertoken)) {
571
+ $argument .= $innertoken[1];
572
+ if(empty($line))
573
+ $line = $innertoken[2];
574
+ } else if($innertoken==";"){
575
+ $argument .= ";";
576
+ if($checkForExternalLink){
577
+ if($this->isexternal($argument)){
578
+ $issue = array("l"=>$line, "t"=> $issueFunction, "i"=>$issuetype, "d"=>$argument);
579
+ }
580
+ } else {
581
+ $issue = array("l"=>$line, "t"=> $issueFunction, "i"=>$issuetype, "d"=>$argument);
582
+ }
583
+ break;
584
+ } else if($flag==1){
585
+ $argument .= $innertoken;
586
+ }
587
+ }
588
+ return $issue;
589
+ }
590
+
591
+ function remove_dir($repo_path){
592
+ $dir=$repo_path;
593
+ $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
594
+ $files = new RecursiveIteratorIterator($it,RecursiveIteratorIterator::CHILD_FIRST);
595
+ foreach($files as $file) {
596
+ if ($file->isDir()){
597
+ rmdir($file->getRealPath());
598
+ } else {
599
+ unlink($file->getRealPath());
600
+ }
601
+ }
602
+ rmdir($dir);
603
+ }
604
+
605
+ function count_total_files($folder_paths, $base, $scan_config){
606
+
607
+ $file_count=0;
608
+ $file_ext = $scan_config['file_extension'];
609
+ $extensions = array();
610
+ if(empty($file_ext)){
611
+
612
+ }else{
613
+ if(strpos($file_ext,';') !=false){
614
+ $extensions = explode(";", $file_ext);
615
+ }else{
616
+ array_push($extensions, $file_ext);
617
+ }
618
+ }
619
+ $enable_extns = $scan_config['type_scan'] == "Custom Scan" && !empty($file_ext) ? false : true;
620
+ $folder_skip_array= empty($scan_config['path_skip']) ? array() : explode(";", $scan_config['path_skip']);
621
+ $skip_path_array= array();
622
+ for($i=0; $i<count($folder_skip_array); $i++){
623
+ $pathParts = explode('/', $folder_skip_array[$i]);
624
+ $n= sizeof($pathParts)-1;
625
+ $folder= $pathParts[$n];
626
+ array_push($skip_path_array, $folder);
627
+ }
628
+ foreach ($folder_paths as $value) {
629
+ if (is_dir($value)) {
630
+ foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($value, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item) {
631
+ if ($item->isFile()) {
632
+ $source_file_path = $value . DIRECTORY_SEPARATOR . $iterator->getSubPathName();
633
+ if ($value == $base && ($scan_config['core_scan'] == 1)){
634
+ $arr = explode(DIRECTORY_SEPARATOR, $iterator->getSubPathName());
635
+ if(($arr[count($arr)-1]== 'index.php' && (count($arr)==1 || in_array($arr[count($arr)-2], array('wp-content', 'plugins', 'themes'))) && !in_array('miniorange', $arr)) || (!in_array('plugins', $arr) && !in_array('themes', $arr) && !in_array('miniorange', $arr))){
636
+
637
+ }else{
638
+ continue;
639
+ }
640
+ }elseif ($value == $base.DIRECTORY_SEPARATOR.'wp-content'.DIRECTORY_SEPARATOR.'plugins' && explode(DIRECTORY_SEPARATOR,$iterator->getSubPathName())[0]=='index.php'){
641
+ continue;
642
+ } elseif ($value == $base.DIRECTORY_SEPARATOR.'wp-content'.DIRECTORY_SEPARATOR.'themes' && explode(DIRECTORY_SEPARATOR,$iterator->getSubPathName())[0]=='index.php'){
643
+ continue;
644
+ }
645
+ $flag_skip=0;
646
+ if (!empty($folder_skip_array)) {
647
+ for($q=0; $q<count($skip_path_array); $q++){
648
+ if(strpos($source_file_path, $skip_path_array[$q])){
649
+ $flag_skip=1;
650
+ break;
651
+ }
652
+ }
653
+ }
654
+ if($flag_skip == 1){
655
+ continue;
656
+ }
657
+ $ext = pathinfo($source_file_path, PATHINFO_EXTENSION);
658
+ $extns = $enable_extns ? true : (in_array($ext, $extensions)? true : false);
659
+ if($extns)
660
+ $file_count++;
661
+ }
662
+ }
663
+ }
664
+ }
665
+ update_option('mo_wpns_total_files', $file_count);
666
+ }
667
+ }
668
+ new Mo_wpns_Scan_Handler;
669
+ ?>
handler/malware_scanner/malware_scanner_cron.php CHANGED
@@ -91,7 +91,6 @@ class Mo_wpns_Scan_Handler_Cron{
91
  }
92
 
93
  function mo2f_download_core_wp($repo_file_path, $scan_config, $reportid, $scanverification){
94
- error_log("downloading core");
95
  $repo_check_status = $scan_config['check_repo'];
96
  $repo_check_status_code=get_option('mo2f_repo_status');
97
  $wp_repo_file=get_option('mo2f_repo_path');
@@ -142,7 +141,6 @@ class Mo_wpns_Scan_Handler_Cron{
142
  }
143
 
144
  function mo2f_download_plugins_wp($repo_file_path, $scan_config, $start_time, $time_limit, $reportid, $scanverification){
145
- error_log("downloading plugins");
146
  $repo_check_status = $scan_config['check_repo'];
147
  $repo_check_status_code=get_option('mo2f_repo_status');
148
  $flag=0;
@@ -206,7 +204,6 @@ class Mo_wpns_Scan_Handler_Cron{
206
  }
207
 
208
  function mo2f_download_themes_wp($repo_file_path, $scan_config, $start_time, $time_limit,$reportid, $scanverification){
209
- error_log("downloading themes");
210
  $repo_check_status = $scan_config['check_repo'];
211
  $repo_check_status_code=get_option('mo2f_repo_status');
212
  $flag=0;
@@ -696,6 +693,7 @@ class Mo_wpns_Scan_Handler_Cron{
696
  $avergaeTimeEachFile=0;//in miliseconds
697
  foreach ($folderpaths as $value) {
698
  $status=$this->check_exec_limit($start_time, $time_limit);//check limit for each file.
 
699
  if(!$status){//wp_remote_get
700
  $decoded_scan_status->average_time_each_file=$this->averageFileScanTime($currentFileScanTime,$nooffiles,$decoded_scan_status->average_time_each_file,$previous_processed_files);
701
  $decoded_scan_status->total_files_processed=$decoded_scan_status->total_files_processed+$nooffiles;
@@ -751,7 +749,7 @@ class Mo_wpns_Scan_Handler_Cron{
751
  $malware_status = 1;
752
  $cfile=curl_file_create($source_file_path, 'test/plain', time().basename($source_file_path));
753
  $postdata = array('file' => $cfile);
754
-
755
  $content_type = 'multipart/form-data';
756
  $issues = $this->mo_wpns_malware_scan_request($postdata, $host, $content_type);
757
  if ($issues) {
91
  }
92
 
93
  function mo2f_download_core_wp($repo_file_path, $scan_config, $reportid, $scanverification){
 
94
  $repo_check_status = $scan_config['check_repo'];
95
  $repo_check_status_code=get_option('mo2f_repo_status');
96
  $wp_repo_file=get_option('mo2f_repo_path');
141
  }
142
 
143
  function mo2f_download_plugins_wp($repo_file_path, $scan_config, $start_time, $time_limit, $reportid, $scanverification){
 
144
  $repo_check_status = $scan_config['check_repo'];
145
  $repo_check_status_code=get_option('mo2f_repo_status');
146
  $flag=0;
204
  }
205
 
206
  function mo2f_download_themes_wp($repo_file_path, $scan_config, $start_time, $time_limit,$reportid, $scanverification){
 
207
  $repo_check_status = $scan_config['check_repo'];
208
  $repo_check_status_code=get_option('mo2f_repo_status');
209
  $flag=0;
693
  $avergaeTimeEachFile=0;//in miliseconds
694
  foreach ($folderpaths as $value) {
695
  $status=$this->check_exec_limit($start_time, $time_limit);//check limit for each file.
696
+
697
  if(!$status){//wp_remote_get
698
  $decoded_scan_status->average_time_each_file=$this->averageFileScanTime($currentFileScanTime,$nooffiles,$decoded_scan_status->average_time_each_file,$previous_processed_files);
699
  $decoded_scan_status->total_files_processed=$decoded_scan_status->total_files_processed+$nooffiles;
749
  $malware_status = 1;
750
  $cfile=curl_file_create($source_file_path, 'test/plain', time().basename($source_file_path));
751
  $postdata = array('file' => $cfile);
752
+
753
  $content_type = 'multipart/form-data';
754
  $issues = $this->mo_wpns_malware_scan_request($postdata, $host, $content_type);
755
  if ($issues) {
handler/malware_scanner/scanner_set_cron.php CHANGED
@@ -14,7 +14,6 @@ class mo2f_scanner_parts
14
  $stop_scan_process=$stop_scan[0]->option_value;
15
  if($stop_scan_process=="1") {
16
  $this->mo2f_end_scan();
17
- error_log( "Scan Stopped" );
18
  return "1";
19
  }
20
  else{
@@ -124,8 +123,7 @@ class mo2f_scanner_parts
124
  $response=$Mo_wpns_Scan_Handler_Cron->mo2f_wp_remote_get($scan_config['type_scan'], $reportid, $scanverification, 2);
125
 
126
  }else{//sending next 100 files
127
- error_log("sending next 100 files");
128
-
129
  $time_limit= ini_get('max_execution_time');
130
  $result=$mo_wpns_scan_handler->get_scan_result_parts($mo2f_malware_db_handler, $files_to_scan, $scan_config, $current_time, $time_limit);
131
 
@@ -256,6 +254,7 @@ class mo2f_scanner_parts
256
  $encoded_scan_configuration=json_encode($decoded_scan_configuration);
257
  update_option("mo_wpns_scan_status",$encoded_scan_configuration);
258
  $mo2f_malware_db_handler->delete_files_parts();
 
259
  }
260
 
261
- }new mo2f_scanner_parts;
14
  $stop_scan_process=$stop_scan[0]->option_value;
15
  if($stop_scan_process=="1") {
16
  $this->mo2f_end_scan();
 
17
  return "1";
18
  }
19
  else{
123
  $response=$Mo_wpns_Scan_Handler_Cron->mo2f_wp_remote_get($scan_config['type_scan'], $reportid, $scanverification, 2);
124
 
125
  }else{//sending next 100 files
126
+ $current_time= time();
 
127
  $time_limit= ini_get('max_execution_time');
128
  $result=$mo_wpns_scan_handler->get_scan_result_parts($mo2f_malware_db_handler, $files_to_scan, $scan_config, $current_time, $time_limit);
129
 
254
  $encoded_scan_configuration=json_encode($decoded_scan_configuration);
255
  update_option("mo_wpns_scan_status",$encoded_scan_configuration);
256
  $mo2f_malware_db_handler->delete_files_parts();
257
+
258
  }
259
 
260
+ }new mo2f_scanner_parts;
handler/mo-block.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <img src="data:image/jpeg;base64,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" style="margin-left: 5em;width: 12em;margin-top: 1px;">
2
+ <div>
3
+ <img src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7N13nFTV3T/wz50+21hgl91l6b2JCGJHxS4WigUZFUuMYyTR50meTMovz5P2S35PJqaZoI5JlICOJbqoKDYUlC4KSO8odYEFtk6/9/z+mF1YYcuUe+fcc+/3/Xqt4DJ757u7M+d87ynfIzHGQAghhBBzsfAOgBBCCCG5RwkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmRAkAIYQQYkKUABBCCCEmZOPxpB6vzwJgFIARABoAnGj1cTwY8Cs84iKEEEK00NzvdQfQrdVHIYAtADbx6PckxlhOnsjj9Y0FcAuASwBcBKConYceBTAHwD+CAf/OnARHCCGEaMDj9Q0G8BCA+wH0aOdh9QBWAVgBYEEw4F+bi9g0TwCav/nfArg9gy9fAuDvAF4PBvxRNeMihBBCtODx+pwAbgPwbQBXZnCJ1wD8VOubYM0SAI/XVwbg50j+ALKdatgH4L8BvEDTA4QQQvSoeZj/HgC/BtAny8slkLwB/mUw4D+SbWxt0SQB8Hh9QwF8BKBS5UtvBPDjYMC/UOXrEkIIIRnzeH2TAPwvgHNUvvRBAFcHA/7tKl9X/QTA4/WNRLLzL1P1wt/0CYAfBQP+1Ro+ByGEENIhj9d3IYDfAbhCw6c5gmQSsFnNi6qaAHi8vnMBLAJQotpFO1aF5DyJ6pkRIYQQ0p7mke7fApiWo6esAXBNMOD/Uq0LqpYAeLy+EgDbkNzmkEsJAM8B+EUw4D+c4+cmhBBiIh6vrwLALwA8iNxvpT8OYFgw4K9R42JqBv9/kfvOH0h+Dw8DuMfj9f0ZgD8Y8NdxiIMQQohBeby+LgB8AP4DQB6nMLoj2dc+osbFVBkB8Hh9owGsBWDN+mLZOw7gNwCeoq2DhBBCstG8pe9RAP8HfG5yzyQDGBsM+DdkeyG1RgD+DH10/kDyF/RHAI97vL7fA3g+GPCHOMdEiKqmzZxlAUMpkottywD0YEApkh9dAbgAOADmBOBM/h2ONv4OAFEAseaPM/4utfx/BMBJAMck4BiSBbuOADgCCceq5s6m7bnEUDxeXx6ABwD8EEBfzuG0ZkWyz70q2wtlPQLg8fomAvg420A0dBzAUwD+Fgz4j/IOhpBUTLt3ViWAoQwYDGAQwAYCKEdygW13AMXQz1keCoBaJN9rNQCqAWk3gF0SsBPA9qp5sw/yDJCQVHm8vh4AvovkXb8e7vjbMzEY8C/J5gJqjABcqcI1tNQdySJCP/R4ffMA/IF2DRA9mHrPd0oT8fg4hbFhDqerL8AGARgAoB/4zTFmwoLTtc0HJz/FWv0XmHrvoyEAXwHYA0i7kEwOdgBYXzVv9rHchkvI2ZpX9f8AwL1IjqDp3UQkq+VmTI0RgA8BXJPVRXKLAXgbwO+DAf9S3sEQc5h276xKOZG4UFbk8YwpYxljoxhjPQHA4XTCYtHLDBoXBwBsAKS1EvAFgDU0YkByxeP1TUBymP9mABLncNKxKBjwX5vNBbJKADxenxXJecHCbILg6DMATwCoCgb8Mu9giDFMu3dWpaLIl8uyPJ4xZQxj7BxFUUpO3w+3kOBwOGGxmrrzb89RJJOCdVJygfFSSgqIWpr7rmkA/gvABZzDyVQDgK7Z9F3ZJgDnAlif8QX0Yy+APwF4LhjwN/EOhojl1hkPVyiKcj1j7CqAXcoYG8BY52vi7A4XrNT5p2MXIH0KYLEELKqaN7uad0BELB6vLx/J/fv/CaA/53DUMCabwkDZJgBTAMzP+AL6cwLA0wCeDgb8dLdB2jTZ4+2RiMevV5Id/mXNc/dpsTucsFpzXUPEcLYD0icSsBjAR7SWgLTH4/VVAvhO80c3zuGoaWow4H8j0y/ONgG4HMm6/EajAPgQwBwAbwQD/gjfcAhP02bOsiiyfHkikbhdUeSrGWNDAZbxXKHd7oTVRp2/yhiALYC0SALmQ8JS2ppobh6vzwVgCoD7AVwL/eyaUdPl2axlyzYBGAFA1cMJdKgWwMsA5tDhQ+YxbeYst5xITJJl+TbGlOsURVZlO5DN7oDNZlfjUqRjNYD0bnMy8F7V3Nlh3gGR3Gg+nOd+AHchuV3WyEYGA/4tmX5xtglADySLgZjFViRHBebRuQPGM23mrJJEPHGboiSmKIpyBWOKW83r22wO2OzU+XMQAvAxIL0pSXijau5sVeqoE/1ors9/L5Id/3C+0eRUWTb1bdTYBRCHWFsn1CADeB/JZOAtKjksrmkzH+0ejyVmKky+kynKeMYUTVblWa022B3Ozh9ItCYDWAVIr0oSXqyaO/s474BIZppL9N6KZKd/PfRTjTZXGAA7t10AAODx+g4BqMjqImI7AeAlJKcIPucdDOnc9dPutdus9qkM7H7G2DUA0/S23GKxwuEUoa6I6cQAvCdBmgMJC6rmzk7wDoh0zuP1nY9kpz8DxlrQl67DwYC/ZzYXUCMBeAHA3VldxDi2AKgC8BaAz4MBvzpnLRNV3DL9oQtlRX6IMWUactRwSJIEh9MNSTLbIJlwagDpVQl4vmrebErkdcTj9UkAzkfybn8agBF8I9KNF4MB/z3ZXECNBOAeAPOyuogxHQawAMlk4CPaScDHtHtn9YzFY99S5MQ9jClDcvvsEhxOFywWIy4+NrStgDRPAv5VNW/2Id7BmFHzCv6rkez0b4G5R5nbc28w4H8hmwuokQD0AFAN860DSEcIwAdIJgPv0KFE2pty93euTCRi31cU5UbGFC577mivv/ASAN6WIP25at5sI2531pXmvuQmJDv96yDWeRi5xgCUZ9uXZJ0AAIDH61sL4LysL2QOCoBVSCYDbwUD/q2c4zGMaTNnORPxxH2yHP+eoiijzi69mztWmx12u4Pb8xPVfQlIf5UkvFA1dzYt+lWJx+sbjmSHfyuAi2DMvfpaWBcM+MdmexG1EoDfAvhJ1hcyp11oHhkAsDIY8NN+5TRNvefRingi/p+KkniQKQr34ztp0Z+hHQOkf0jAX6vmzaatwGnyeH1uABfj9J1+2lU0CQDg/wUD/p9mexG1EoArkOWxhARAckvlWgDLmj+WBwN+Km/ajske7yUJOfF9psi3MqbtSv5USZIFDqeLFv0ZXxxAVfP0wCreweiVx+srBXApgMuaP8YC0MV7VXBXBgP+rKel1EoA7ACOQ9xTAfVsO04nBMuCAf8uzvFwd8v0hyYpTPm5oigX8BzmP5sEp9MFiRb9mc0KCdIvq+bN/oB3ILx5vL5BON3ZXwZgKN+IDKkBQPdgwB/P9kKqJAAA4PH63gAwWZWLkY4cAbAcp5OCdcGA3xT7l2+644FbFcb+G2Dn846lLVTj3/RWSZB+VTVv9ru8A8kFj9dnQ3LtV0tnfymAMq5BmcObwYB/ihoXUjMB+A6Ap1S5GElHE4A1ADYgeS7DZgBbggH/Sa5RqeiW6Q9NluXEzxmYbhea0rw/aWVN84jAO7wDUYvH6+uK5P77kc0fowGMB5DPMy6TejQY8D+txoXUTAAGANitysWIGg7jdEKwGckiRZuDAX8t16jScOuMh6ckEvH/YUzRbccPABIkOFxU7Iec5XMJ0q+r5s1+i3cgqfJ4fcVIdvCtO/uRoH34ejIwGPDvUeNCqiUAAODx+r5EMjMk+nUIrRKC5o+9AI5mU1NaTVM8j0yJJ2K/VBRltL7m+NvmcLhgsZqtDDlJwzoJ0i/0kgg0n+HSA0B/nO7gWzr8rErLEs1tCAb856p1MbUTgP8E8EfVLkhySQFwFMkE4XCrj0Nn/P2IGotP2jLl7kfGJRLxP8uyfJkIHT8AWK122B2035+k5BMJ0ver5s1eq8XFmxdjlyHZiVc0f7T+e8v/9wDttxfV94MB/5/UupjaCUAPAAcB0Eoo42IAanA6ITiKZKXDCIBw85+tP8783Jn/n0jEY+XRSPiniUTiJoAJ0zC1bPkjJA2KJElv2Wy231lt9mok20pXqw93J//f+nN5SHbmLR17Cagiq5ElAFSqWUlW1QQAADxe31tI1m4mhBBCiDoWBAP+W9W8oBZ3W3M0uCYhhBBiZnPUvqAWCcDbSBYFIoQQQkj2jiPZt6pK9QQgGPDHALyk9nUJIYQQk3qpuW9VlVYLruZodF1CCCHEbOZocVHVFwG28Hh9m5DcV0oIIYSQzGwOBvyjtLiwlluu5mh4bUIIIcQM5mh1YS0TgBcARDW8PiGEEGJkUST7Uk1olgAEA/5qAM9pdX1CCCHE4J5r7ks1oXXVtd8B0KRsLCGEEGJgcST7UM1omgAEA/6vAczV8jkIIYQQA5rb3IdqJhd11/8fAF2cMkcIIYQIQEay79SU5glAMODfDSCo9fMQQgghBhFs7js1lauT136D5HGzhBBCCGmfgmSfqbmcJADBgH87gFdz8VyEEEKIwF5t7jM1l8uz13+D5FnyhBBCCDkbQ47u/oEcJgDBgH8TgPm5ej5CCCFEMPOb+8qcyOUIAAD8AkAix89JCCGE6F0CyT4yZ3KaAAQD/o0A/pzL5ySEEEIE8OfmPjJncj0CAAA/B/AVh+clhBBC9OgrJPvGnMp5AhAM+EMAZuX6eQkhhBCdmtXcN+YUjxEABAP+haBtgYQQQsirzX1iznFJAJo9DqCO4/MTQgghPNUh2RdywS0BaD7i8Me8np8QQgjh7MdaHvfbGZ4jAAAQALCCcwyEEEJIrq1Asg/kRmKMb3E+j9c3CsBaAHaugRBCCCG5EQcwNpdFf9rCewSgpULg73jHQQghhOTI73h3/oAOEoBmvwCwiHcQhBBCiMYWIccV/9rDfQqghcfr6wZgDYABvGMhhBBCNLAHwPhgwH+CdyCAfkYA0PwDmQygkXcshBBCiMoaAUzWS+cP6CgBAE6tB5gJOjaYEEKIcTAAM/Uw79+arhIAAAgG/PMB/Ip3HIQQQohKftXct+mK7hKAZr8E8AbvIAghhJAsvYFkn6Y7ulkEeCaP11cIYCWAkbxjIYQQQjKwGcDFwYC/gXcgbdFtAgAAHq9vIJI7A7ryjoUQQghJw0kkV/zv5h1Ie/Q6BQAAaP7BTQHtDCCEECKORgBT9Nz5AzofAWjh8fouAvAugGLesRBCCCEdqAVwYzDgX8U7kM4IkQAAgMfrOxfAhwBKecdCCCGEtOEYgGuDAf+XvANJha6nAFpr/oFeDuAg71gIIYSQMxwEcLkonT8gUAIAAMGAfxuACUiWUySEEEL0YA+ACc19lDCESgAAIBjw70UyCdjKOxaiPqfDDrvNxjsMQlRlt9ngdNCJ5wa1FcnOfy/vQNIlzBqAM3m8vlIA7wM4j3cspGNulwsVZSWoKC9Fz7JSlPcoQUFBPtwuJ9wuJ1wuJ9wuF1xOByyWZE4qyzLCkSjCkSgizX+GIxHU1Tfi8JGjOFR9DNVHalB9rAbxeILzd0jMyG63oby0BOVlJehZXoqKsh7oUlQAt8vV6nWd/LBarQAARVEQicYQjkRava6jaGxsQvXRGhw6cgyHq4/h8JEahCMRzt8hScE6ANcHA/5jvAPJhLAJAAB4vL5iAAsBXMw7FpJUkJ+HEUMHYsSQgehdWY6K8lIUFxVq9nyMMdQcP4nDR2qwd99BbN6+Czt2fYVYPK7ZcxLzcdjtGDKoH0YOHYT+fSpRUVaCku5dIUmSZs9ZW9+Aw9XHsP9gNbbs2I0t23ejsSmk2fORtK0EMCkY8NfyDiRTQicAAODx+lwAfg/gu7xjMSOX04Fhgwdg5LBBGDlsIPr26qlpo5iKeCKBXXv2YdO2Xdi8bRd2f7UfsixzjYmIxWq1YmC/3qde14MH9OU+NcUYw9cHDmHztt3YvG0Xtu3cg0g0xjUmE/sbgB8GA36hh2mETwBaeLy+mwE8D6CEdyxG53Q6MH7MKFx20ViMHDrw1PCmXkWiMXzx5WYsW7UWG7fuhKIovEMiOmSxWHDO8MG47KKxGHfuSLicDt4hdUiWZWzevhvLVq3FmvWbEKVkIBdqADwQDPjf5h2IGgyTAACAx+urADAXwDW8YzEaSZIwcuhATLh4HMafd47uG8f21NY3YPnqdVi26gt8feAw73CIDvTtVYHLLhqHSy88T9PpKi1FojGsWbcRS1d+gc3bd8NI7bqOLELySF/DNByGSgAAwOP1SQD+C8BvANCy2ywVFxXi+qsuw4SLxqJb1y68w1HVvgOHsWT5GixethrRGK0ZMBOnw46Jl12IKy8djz69KniHo6oTJ+uwdNVavP/xMtTW6/IMGtHEAfwfAE8EA35DdZiGSwBaeLy+cQBeAjCYdywiKulWjJuvvxITL70Adruxt+XVNzTh3Y8+xQeLV9LKa4Nzu1y4buLFuPHqy1FUmM87HE3F4wksXv4Z3n5/CWpOCLtOjbedAGYEA/4veAeiBcMmAADg8foKADwJ4AHesYiivEcJbr1hIiZcNFb3c/tqC4XCeH/xcrz70TJabW0wBfl5uPHqy3D9xEuRl+fmHU5OybKMpavW4q33FqP6aA3vcETyPIDHggG/YQ+jM3QC0MLj9U0H8BcAZbxj0auSbsWYPvVGXHz+uaf24ptVNBrDB0tWYP47i2iVteBcTgem3nQNrrvyEjgFXbeiFkVRsPLzL/HK/HdpRKBjRwA8Hgz4X+EdiNZMkQAAgMfrywfwGAAf6FTBU6xWKyZdMwHTbr6WKpWd4URtHea9ugCrv9jAOxSSgQvHjca9d96CbsXGWruSrWgsjqq3P8TCRUtpe+w31QLwA3gyGPA38Q4mF0yTALRoLh70QwCPAzD2JGAnRgwdiAdmTEVlRQ/eoejaxq078XxwPg2fCqK8Rwke8EzFOcNp+U9HDh4+iudfmo8t23V9ZH0uNCE5Qvx7kYv6ZMJ0CUALj9dXBuCnAB4BYKqxweKiQtx9x8249AKqopyqeCKBtz/4BG8u/JiqDOqUw27H5ElX4ebrruBetEckyz9bhxf//bYZdwzEADwD4LfBgP8I72B4MG0C0MLj9fUB8HMA9wEw/Kq3saNH4JH770RBfh7vUIR08PBRPPnsC9h/qJp3KKSV3j3L8djD99BoVoYam0J4Zs6rWLthC+9QckEG8C8AvwwG/Pt4B8OT6ROAFh6vbyiAXwG4AwDfWrYasFqtmDHtRky65nLeoQgvFo9jzktvYsnyz3iHQgBceekFuH/GZDjstIYlWwsXfYqXqt416toABuDfAP4nGPBv5x2MHlACcAaP1/cWgFt4x6Gmku5d8di378ag/n14h2Ioy1evwz9ffJ12CnDicjrwrbtvw6UX0lSWmnbt3Ycn//4iao6f5B2K2hYEA/5beQehJ5QAtOLx+kYA2AjAMPvgzh8zEt777kS+yfY+58rhI8fwl2dfwD4qK5xTfXpV4PGH70FFWSnvUAypKRRG4F+v4vP1m3mHoiYFwDnBgN8U8xypMExHp5L/gYF+JlMmXY3vf+c+6vw1VFFWil/9+LsYO3oE71BMY+zoEfjVj79Lnb+G8vPc+P537sOUSVfzDkVNFiTbeNKMRgCaeby+kQA2wAAJgCRJuG/6ZFw38RLeoZiGoij4+7zX8MmKz3mHYmhXXHI+vn3v7aYvVpVLHyxegX+98qZRDhhSAIwOBvyGGtrIFL2LTjPE3b/NZsX3HvJQ559jFosF3vvuxK03TOQdimHdesNEeO+7kzr/HLtu4iX43kMe2GyG2CRFowCt0AgATt39b4Tgq/9dLie+/537MGrYIN6hmNp7Hy3DvH8vMModE3eSJOHeO27BDVdfxjsUU9u0bRf++PS/EIlEeYeSLYbkWgDTjwJQKp30PxC88y/Iz8N//+AR6vx14IarL8OjD95Fd6oqsFgsePTBu6jz14FRwwbhv3/wiBFqiEigUQAAlADA4/WNQnLvv7CcDjt833sQ/ftU8g6FNLv0gvPwoGcq7zCE96BnKlWs1JH+fSrh+96DRjg35I7mtt/UTJ8AQPC7f6vFgse999Iefx26asKFuGPy9bzDENYdk6/HVRMu5B0GOcOg/n3wuPdeWMUe4aJRAJg8AWjOAG/nHUemJEnCw/fdgTGjhvEOhbRj6qSrcd2VtCAzXdddeQmmGmsLmqGMGTUMD993ByRJ2HsnALjd7KMApk4AkDwDQNhX8IxpkzDhonG8wyCduO+uybhw3GjeYQjjwnGjcd9dk3mHQTox4aJxmDFtEu8wsiEh2QeYlmkTAI/Xdw6A23jHkakbr56Am6+7gncYJAWSJOHRB+/C8CEDeIeie8OHDMCjD94l+p2ladx83RW48eoJvMPIxm3NfYEpmTYBgMBz/0MG9oPn9pt4h0HSYLfZ8L1v340uRQW8Q9GtLkUF+N6376ajfAXjuf0mDBnYj3cYmTL1WgBTJgAer683BL37L8jPw2Pfvlv0BTimVFxUiFnf8tDdbRskScKsb3lQXFTIOxSSJqvFgse+fbfI2wNva+4TTMesvchdEPDuX5IkfOeB6ejWtQvvUEiGRg0bZLT66qqYMulqqmEhsG5du+A7D0wXNbmVAMzgHQQPZk0AhPxl33Tt5TjvnOG8wyBZuu3mazBiyEDeYejGiCEDcdvN1/AOg2TpvHOG46ZrL+cdRqaE7BOyZboEwOP1DQUgXGWRwQP6YvrUG3mHQVRgsVjw3YdmoKiQ1gMUFRbguw/NoKqJBjF96o0YPKAv7zAyMcbj9Znu7sqM7zrhMj27zYZHH7iL5v0NpLhLER6gSoF4wDMVxV2KeIdBVGK1WPDoA3eJupBTuL4hW2bsUYT7Jd96w0SU9ejOOwyisgvHnoPRI4fwDoOb0SOH4MKxpt2BZVhlPbqLeiqmcH1DtkyVAHi8vrEAhGpxy0qFfTORFDxw11RR75ayYrfZ8MBdNAJiVLfeMBFlpcLdtAzyeH0X8A4il0yVAEDADO++uybDbjdfB2EWZT2645YbruQdRs7dcsOVNKplYHa7TdRqjsL1EdkwTQLg8fokANN5x5GO8eeNojr/JjD5hqvQo6Qb7zBypkdJN0y+4SreYRCNjRk1DOPPE67U/nSP12eaftE03yiAywAIU+zB6XRg5vRbeYdBcsBut+H+GVN4h5Ez98+YQqNaJjFz+q1wOh28w0hHBYAreQeRK2ZKAIQa2rn2iovRvWsx7zBIjowZNQzDBvfnHYbmhg3uT6NaJtK9azGuveJi3mGky8M7gFwxRQLg8fpsAO7gHUeqHHY7brqWDvoxGzNUCDTD90i+6aZrr4DDbucdRjpu83h9Qg1bZMoUCQCAawCU8A4iVRMvu4AOjTGh0SOGYGA/YWap0jawX2+MHiHUJhyigi5FBZh4mVCL64sBmKLqmlkSgLt4B5Aqm82KW66/kncYhBMj3yEb+XsjHbvl+iths1l5h5EOoaaMM2WWBECYJceXX3w+HfZjYmNHD0ffXhW8w1Bd314VGDvadJVWSbNuXbvg8ovP5x1GOoTpM7Jh+ATA4/X1gCCr/60WCxX9MTlJkgx5pzxl0tWinhRHVHLrDRNFKmde6vH6+vAOQmvC/DayIEzaOfbcEabaD07adsHYc9Ct2DijQN2Ku+ACKvlrej1KumHsuSN4h5EOYfqOTJkhARjPO4BUTbhoHO8QiA5IkoRLLhjDOwzVXHrheXT3TwAI18YJ03dkygwJgBBZXEF+Hu2PJqcI1lB26PKLjfO9kOyMGTUMBfl5vMNIlRB9RzYoAdCJS8aPEW2VLNFQ78py9DHAYsD+fXuhsqKMdxhEJ2w2Ky4ZL8zoluEzV0MnAB6vrxeAct5xpGIC3SWRM1x24VjeIWRtwkXifw9EXQK1dV09Xt8g3kFoydAJAAS5+68oKzV0ARiSmUsvEHvu3Gqx4JLx5/EOg+jMwH69UVFWyjuMVAnRh2SKEgAduPQCaiTJ2boWF2HE0IG8w8jYOSOGoKgwn3cYRIcEavOE6EMyZfQEQIhVnOeMGMw7BKJTIpfOHTWcXtekbQK1eUL0IZkyegKg+8kml9OBATT8T9oh8gjASIFjJ9oa0K83XGIcEzzW4/UZtp807Dfm8fr6A+jOO47ODB3UX6TqWCTH+vepRJ7bxTuMtBXk5xliFwPRhtViwdBBQhx/XQBgKO8gtGLjHYCGhJi7EfkOT01Ha45j6fLPsH3nHuzcvRdFRYUYMqg/Rg4bgisuu1DoxXDZsFgsGD5kAL74cgvvUNIyfMgA0/7OAIAxhk+WrcbmbTuwY9de1Nc3YPDA/hg6eAAmXHoBepTo/t5EcyOGDsSXm7fzDiMV5wPYyjsILRg5ARBi7oYSAGDhB4vx1D/mIRQKf+PzGzdvw+tvvosRbw7Gj/7jEfTu1ZNThHyNHDpIuATAzK/r/QcO4Xd/fgZbtu38xue/3n8Qi5Ysw/Mv/huPPnQvJl1n7nM/BHqNjAcwj3cQWjDy2PO5vAPojNvlQv8+lbzD4Mr/5wCeePLZszr/1rZs24mHH/sJvtxkyCS8UyOHibcVWaDGXVVfbtqKhx/7yVmdf2uhUBhPPPks/H8O5DAy/enfpxJulxDTW7rvSzJl5ASgF+8AOjN4QB9YTDz//8myVXhv0ZKUHhuNxfC7Pz2NULj9RMGoevUsE2odQJ7bhV4mrP4XCofxuz89jWgsltLj31u0BJ8sW6VxVPplsVgweIAQB+4Z9i7NyL2P7n9pPct78A6Bm8amEP40+59pfU31kWP4+5yXNIpIvyRJEqlwCirKSk05///3OS+h+sixtL7mT7P/icamkEYR6Z8gbaBh5x4NmQB4vL58ALo/T7W8rIR3CNxs2rId9Q2NaX/dys/WaRCN/omUAPQsx9EekwAAIABJREFUFydWNWXy2qxvaMSmLUIshNOEIG2g2+P1FfMOQguGTAAgSMbWU6BGXW3bd+7J6OuOHqtBQwaJg+gqBOpUy034um5oaMTRYzUZfW2m7wUjEKgNNOSeVqMmALof/gfEatTVtnvv1xl/7Z6v96sYiRgEaiiFilUt2bwms3kviE6gNlCIm8p0UQLAidNhR7di3c9SaCYajWbxtaktsjISkaYARIpVLdm8JrN5L4iuW3EXOB123mGkgkYABKL7bK3cpAulSGbKy0qEeL1IkiTKvC7RgeTrRYiEUfd9SiaMmgDofsFGj5JuvEMgAnHY7ehSVMg7jE51KSqEwy7EHR3RCUHaQkMO1xo1AdD9pmm3y8k7BCIYEV4zIsRI9EWQ14zu+5RMUALAiSAVsIiOiFAMSIQYib4I0hYKEWS6jJoAuHkH0BmXGFkv0RERXjMixEj0RZDXjO77lEwYNQHQfbYmyLAX0RGXU/+vGRFiJPoiSFuo+z4lE0ZNAHSfrQmS9RIdEaGhFCFGoi+CtIW671MyYdQEQPfZmiDzXkRH3G79N5QixEj0RZC2UIgg02XUBMDBO4DOCFL8guiI06H7l7UQMRJ9EaQtNOQL26gJgO6P14rF47xDIIKJxfT/mhEhRqIvgrSFuu9TMmHUBED3p8WEw+Yt/0kyE45EeIfQKRFiJPoiSFuo+z4lE0ZNABp4B9CZiInrf5PMhCP6f82IECPRF0HaQt33KZmgBIATaihJuiICvGZEiJHoiyBtoe77lEwYNQHQ/XBNOGzuodJsDrYR4VAcLYjQUIoQoxbo9Zw5QdpC3fcpmTBqAqD7bC0sxrCXZnpWlGX8tRXlPVSMRBwidK4ixKiFbF6T2bwXjECQtlD3fUomjJoA6D5bEyTr1czQwQMz+ro8txuVJm0wRVhgJ0KMWqisKEOeO7NaMZm+F4xCkLZQ931KJoyaAOg+W6s5fpJ3CFyNGDooo68bOmSAKYdM44kEaut0/7JGbV0D4okE7zByTpIkDB0yIKOvzfS9YBSCtIX6f/NlgBIATg4fOcY7BK569+qJW268Oq2vsVqtePj+GRpFpG/VR2vAGOMdRqcYYzhy9DjvMLh4+P4ZsFqtaX3NLTdejd69emoUkRgEaQt136dkwqgJgO6HayLRGE7W1vMOg6tHvnUPystKU378jNtvNe1wafWRGt4hpEyQBl11QwcPxIzbb0358eVlpXjkW/doGJH+naytRyQa4x1GKnTfp2TCqAmAENmaWRvKFm6XC/5f/QTDOxkCtVgsuPvOKZg547YcRaY/h6rFea2IFKvaZs64DZ47JsNi6bhpHT50EPy/+okodfA1I1AbKESfki4b7wA0cpB3AKk4dOQYRgw15x1ti16VFfjr73+JV+e/g3c/XIIDBw+fGup2uZwYNmQQvA/MMO2df4vDR47yDiFlIsWqNpvNiofuuwsTLhmPwPMvYduOXadqI0iShF6VFbjx2itx59SbOk0SzOCQOAmAEH1KugyZAAQD/kMer68BQCHvWDpy2MR3Sq1ZLBbcddstuOu2WxAKhbFrz1foUlSIPr0rTbngry0CNZRCxaqVoYMH4o+//RkYY9i3/yDq6hswaEA/5OUZ8lTZjAnSBjYEA/5DvIPQgiETgGY7AIzjHURHDlWb906pPXl5boweNZx3GLojSEMJQKxYtSZJEvr26cU7DN0SpA3cwTsArRh5DGo77wA6s2vvPiFWdhO+Dh4+iqZQmHcYKWsKhUVp2AlHjDHs2ruPdxip0H1fkilKADhqCoXx9QFDjiwRFW3evot3CGnbsn037xCIzn194JAoia3u+5JMUQLAGTWUpDObt4mXAGym1zXphEBtnxB9SSYoAeCMGkrSEcYYtu7YwzuMtG3dsZumt0iHBGr7hOhLMmH0RYAMgK6XkW/fuReKotCWINKmrw8cQmNTKOvrFLgTGNYrhNLiKAqcMooLGcq7Jd8adSEr6pusqAtZUH3Cjk1fudAQSq+i3ZnqG5pw4PAR9O5ZnnXsxHgURcH2nXt5h5EKBgMvAjRsAhAM+EMer+8AgN68Y+lIKBzB3n0HMbCfrsMknGzelvldUp/SCM7p34DBFY0o7/rNE9eKCu0oyGv77c8AfF3twIa9bny+PQ9fHXFk9Pxbtu+mBIC0ae++gwiJcQjQgWDAn30GrlOGTQCabYfOEwAA2LR1FyUApE0bt6Z/8zG4ZxMmnnMCAyqa2n2M3db+iJMEoF95DP3KY7j14jps2uvGWyuLsG1/elXrNm3diesnXprW1xBz2LRVmHUthh3+B8yRAFzDO4jOrPhsHSbfOJF3GERn6hsasTmNhnJAeRg3nX8UlSWdr6y221KfGRvVP4xR/cPYecCJl5d0xc6DzpS+7svN29EUCiOfit+QM6z4bB3vEFJl6ATA6BPPn/MOIBX7D1Xjq/2GrDRJsrBizXrIitLp4yQA146pwUPXf51S52+zSrBY0l8aM7hXFD/1VOOWi+pSWliTSMhYuWZ92s9DjO2r/Qex/1A17zBS9QXvALRk9ATgY94BpGrpyrW8QyA6s2xV56+JAncC375hP64eU4NU+3RbB8P/nbFagDuuqMV/3XkUhXlyp4//dJWh20+SAcHaOmH6kEwYOgEIBvz7GGNCnKO6Ys26lO72iDkcqj6KPV8f6PAxld3C+I9b92JAeftz/W2x27N/25/TP4z/e/8h9C6Jdvi4XXv2ofqoEG9BkgOyomDFGjGG/xljNcGA/2vecWjJ0AkAACTiMSFWcNbVN2LDZkNPN5E0LFvdcSM5pLIR3hv3o8Dd+V34mdKZ/+9I10IFP7vnCIb36XjaYelKGgUgSRs2b0ddfSPvMFKiKHJ6mbWADJ0ATJs5S4rFot15x5GqpSkM+RLjY4xh2er2XwtjBtThvqsOwmHPbMTIZlXvbe92MvzXHccwfmj7beWy1WupKBABIFYbJ8uJ7tNmztJ1HZlsGToBiIZD4+PxaD7vOFL1+fpNOHGyjncYhLO1G7ai5vjJNv/tspEncNflh2G1Zt6hWq3qtml2G8N3J9fg6vPq2/z3Y8dPYu2Grao+JxHPiZN1+Hz9Jt5hpEyR5QIwnMc7Di0ZOgFQGLueKQpkOcE7lJQkEjIWvL+EdxiEszcWftTm5yedfxQ3j8/ulD2LRYKkwT2NJAH3XXcSt01oO3Fp73si5rHg/SVIJNKfsuKBKQoYY2ACbCPPhqETADA2EQDi8RjvSFK2eNlnwsyREfVt2LIDu7/a/43PWSRg+oTDuHzUiayvb81g+186Jl9Sj2/dcPysHQm7v9qPDVsMW1GVdKKuvhGLl33GO4yUyUpLosKu4hqIxgybANx42312AOMBICFQAhCLx/HOh5/wDoNwcuadssPGcP81+3HeQHWmhtQe/m/LFec24rGpR+GwfXOagkYBzOudDz9BLB7nHUbKFPnUSMUl02bOMmzBPMMmAFar7VJIKADESgAAYNEnK1U5AIaIZdvOPdjW6oCUPKeMh2/YhyGV6i1GzqQAUCbGDg7jR9OPIN91eqHitp17sW2neCcbkuw0NoWw6JOVvMNIi3JqBACFYLiIZyxaMmwCwIDrTv2dMSQS4mSfkWgM7360jHcYJMfmv3P6DrlrQQKP3vQ1eqVQ2S8duRgBaDG4VxQ/u7sa3QpPz/u2/h6JObz70TJEouLchCnN8/8tGHAtx3A0ZdwEgClXtv7/WFSIk6dOee+jZbQWwES2bN+NjVt3AgAqukXx6E1foaRI/UZT6zUAZ6osieN/7j2MypJkAr5x605sEecceJKluvpGvCfYzczZi8aZYQ9qMWQCMG3mLCeAca0/F4uJlQCEIxG88NoC3mGQHJBlGc+/NB8AMKA8BO+N+1Do1mbnSi5HAFp0K5Txs7urMbgyWTXw+ZfmQ5bFWA1OsvPCawsQjojV9spnjxZf0NynGI4hEwBFlscxpnzjEHOmKIjHOi5bqjfLV6/Dlh10t2R0CxctxcHDR3FOv0Y8eN1+uOzadY4q1gBKS75LwY/uOoLzBoVx8PBRLFy0lE8gJGe27NiN5Z1UtNQbRZbbKlrlBMNYHvFozZAJQEKW2zyEXLRpAAB4PvgG3S0ZWM2JWlS9swgXD6uF58oDsFm0rZiXq0WAbXHYGB6fdhRXjG5E1TuLUHOillssRFuyLOP54Bu8w0hbQm57rRiDMRcCGjIBYIpyQVufj8ejwpUkPXj4CN0tGdi8V9/CFSMOYfJF1SkdsZstiWMCACRrGnzrxuO4fuwxzHv1La6xEO0kR7WO8A4jPYxBTrQ79dZmnyI6YyYAUNocrmGMCTkKUPXOIhw/SXdLRrN+01b0yVuEq87NzWl5kiTlJMlIxe2X12J4yadYv4lKBBvN8ZPJUS3RdFwxlo3r4B+FZbgEYNrMWcVQWP/2/j0WVXdbVS5EozE8M+dV4UYvSPsam0LY9sVfMX5w7hI7i87e7deMbcDXm5+hmhcGwhjDM3NeRVSgbX8tEu3f/QPAoGkzZxXnKpZc0VmTkD05nriUgbV7o5NIxFsXeRDG5m27aA+1QTDG8Mbrf8ElQw7k9HklLQ4ByNKk86vxzluzKbk1iPnvfITN23bxDiNtjCmd9QsSGC7OVTy5YrwEQJE7/SWJOA0AAK+//SHtoTaADxctwPi+ua+Lznn6v02SBFw3ei0++vgd3qGQLG3Zvhuvv/0h7zAy0sHc/ykMuDAHoeSU4RIAxtpeANhaVMBpACB55/i3f76E+gYqECSqnbv3oEv8BbgduR+F0uMIAAAUuhX0db+KnbupTLCo6hsa8bd/viTsSE4nw//NmOEWAhowAWBjOnuMIsuIx8WqCdCitq4eswV+o5lZY1MICxc8g4qufEag9LYGoLX+5VF88O7faT2AgBhjmP3Pl1BbV887lIzIsgzGlM4fCOPVAtBxk5C+qfc82o8xVprKYyMh9Q5YybWNW3fitQViDrWZlaIoeOq5l9G72yFuMeh1BKDFoPIjeOq5l6EoKTXGRCdeW/DhqTLWIkrjsLiyaffO6qdhKDlnqARATsQvAVK7M04k4sKdEtja/HcW4eOlq3mHQVL0jxdexxfrN2JYb36Jpx7XALQ2bkgYX6zfiH+88DrvUEiKPl66GvMF3PLXQlHkdBeFG2odgLESAEU5J53HR8LijgIAwHPB+VizbhPvMEgnXnnjXXz0yUr0LmlAgYvfDhTeRYA6U1ygoF9ZEz76ZCVeeeNd3uGQTqxZtwnPBefzDiMr8TRvAhkwUqNQuDBUAsCYMiKdx8fjsbYOfhCGoij42z+DdMa6jr338TJULfgQsVgEw3vz3X2i8/4fADB6QByxWARVCz7Eex+LdYqcmWzbuQd/+2dQ6OkaRVGgpF1mnaXVx+idwRIANjTdrwkLPgoQjyfwxOw52HfgMO9QyBlWrlmPOS/NP3USJe9lmzpfAgDg9M8oFotgzkvzsXLNeq7xkLPtO3AYT8yeg3hcmxMrcyXDKeBhasfBk2ESgKtunm4Da78CYHvisWgnJSD1LxSO4H+f/CcOVR/lHQpptm7DVjz1/MuItjoKNRrn/XbTfwYQiZ2OMRqJ4KnnX8a6DVQuWC8OVR/F/z75T4TCYtZSacEUJdN2f9C0mbOsasfDC+8WSTVud/4QSHB0/sizib4WAEhuD/yF/yns2ruPdyim9+mKz/HHp/+FUFMTWt/3x3jPNum//8c3K8gyhJqa8Men/4VPV3zOKyTSbNfeffiF/ylht/u1Fk9kvADcCYZBasbCk2ESAEmSOt3/355YNJLBXJD+NDaF8Js/PYv1m7bxDsW0Fry/BM/861VEY9GzVhfzHgEQoP//xggAkFylHY1F8cy/XsWC95fwCYpg/aZt+M2fnjVEnQbGlJQq/3VgtFqx8GaYBIABWS3OiETEHwUAkgcH/WH2HCxdtZZ3KKbCGMML/16Al6oWgjGGeOzsQlM19TYOkYnlaO3Zo6vxWPIY75eqFuKFfy+gIlg5tnTVWvxh9hwhD/hpSyKe3VBctn2NnhgmAch2dWY0Es42K9QNWVHwzJxX8PYHn/AOxRRkWcZTz72MhYuWNv9/26+j3YccOFZHSUB7DhyzYsf+tn8+LT/ThYuW4qnnXoZsgBE7Ebz9wSd4Zs4rkAVe7d+aoihIZL3zyzg7AQyUAGBIthcINYk/t9WCMYbg6+/gmTmvIMp98tm4jp+sxa//8AyWf7bu1Oc6mk5avqUgF2G1Se+7AN5f42r331r/TJd/tg6//sMzOH4yd0cpm000Fsczc15B8PV3DDXi0tbIXAYMsxNAMsIvd9rMWVIkHAoxprTfgqQor6AITqdbjbB0o7KiBx5/+F706lnGOxRDWbdhK56e88pZ86KRcFO7jabboeDX91fDbsv9HVW3YgdcTn0uYI7GJHz7ia4IR9vOUiRJgsud/43PFeTn4Tv3T8d5o4fnIkTTOHDoCP7y7DwcPGysXUWJRFytBCAsSVJ+1dzZwneexhgBYBgAxrLu/AEg3NSY6sEQwjh4+Ch+9tsnsWT5Gt6hGIIsy3jxtbfxxFNzzur8GVM6vGMKxyxYv9tYCaYalm5wttv5A8kRrTPfl41NITzx1By8+NrbNCWgkiXL1+Bnv33ScJ0/Y0zN0u9uMAxQ62I8GSIBYEwZyFQqs8KYgnCT8Y7bjcXjeHbuv/HUcy8bZjEPDzXHT+KXTzyNdz78tO2OPoWX4cI1RYhx2BGg1xmAcFTCa5+mkBS19eNmDO98+Cl++cTTqDl+Uv3gTCIajeGp517Gs3P/jViWi+T0KB6PqT2VQQmAXsiynHYBoI5Eo2EVForo07LVa/GjX/2RtgqmSVEUfLB4BX786z9h154Oai2kMNF+ot6KhZ8XqRhdinS6CCD4UR6O16XQFHUQ/649+/DjX/8JHyxeIXR5Wh7Wb9qGH/3qj1i22pg7hxRFVr3kOwP6qnpBTgyxJFlhrI/a1ww11aOoS3e1L6sLR2tOwP/X53D+mJGYOX0ySroV8w5J13bt3YfnXpyPr/Yf7PSxqR65u2R9AcYOCqFPqblHY7bvt+H9z1KbvevsZxsKRzDn5TewZPkaPHj3VAzqr3qzYCg1J2ox95U38fn6zbxD0ZRK8/5n6q3FRXPNEAkAGFP9lyEnEohGQnC68tS+tG58vn4zNm7Zgak3XYObrr0cVqs+F4jx0tgUwsvz38XiZZ+lNXwoSVKnj2cMCH7cFT+84wishhiHS19CBp5+swCp/GhTTawA4Kv9B/Hz383GxMsuwF1Tb0RBvnHfw5mQZRnvfPgp5r+zyPA7hBKJuFYjQpQA6AVjiia/jHCoEXaHCxaLcVvoaCyOl+e/i6WrvsDdt9+MMaMMs8MlY7IsY8nyNXj1zffR0Jh+gSiLxZpSnfHDx+34eH0Rrh1rnO2n6Xj90zwcPJZa0mmxpJecMsbw8dLVWLNuE+6cfD2uvHQ8JbhIDve/+Nrbhlvk1xbGWNrH/aZxdUMkAIbYBjjpzgd2MEUZrMW17XYHCoq6anFpXerfpxJTJl2N88eMTOuuywhi8TgWL/sMb7//SVZ7zBVFRjQSTumxVivw4+nV6FGsfREqPW0D3H/Uih8+U4xUF+87Xe60k4DWunctxs3XX4GJl10Ah92e8XVExBjD5+s3442FH2Hvvs6nsYwiGg1rWeJ92/x5Twm//9QYCcAdDzQwpmhWYcWdV3DWHmSjq6wow5Qbr8LF48819AgIAESiMXy4ZAUWLvoUdfXq7ACJRsJnnQXQnoEVMTw2Vfs7sq5dHHC7+CcAjAE/+0cX7DiQ2gCkxWKF06XO1skuRQWYdM3luPbKS+ByZnR2mDAURcHKNV/ijXc/xsHDR3iHk1OJeEzDu38AQMP8eU9xWMmrLuETgGkzZ3UJh5pqtT5tvbCoK2x2YzcYbSkr7Y6brr0cF48fg/w8Y+1frzl+EktWrMEHi1eofsiJLCcQi6Z+ZOr0K2pxyUhtt58WFzmQ5+afACxc5cLz76aeUDucLlit6s5WFuTn4bqJl+DKS8ajpLuxRviaQmGsXLMe73z4KY4cO847nJxLZwQuG5IkFVfNnV2n+RNpSPgEYLLHOyYWi6zr/JHZsVgsKOrSHZLB74bbY7fZcN7o4Zhw0TiMGTVU2PnUcCSC1V9swNJVa7Ft515Ny5ymMwrgdDD8dEY1ivO1K2jTpdCO/Dy+y36O1Vrwn7OLEY2lNr2k5t1/WyRJwrDB/THhorG4cNxouF2q1BPLOVmWsX7Tdixd9QXWbdiKuEHONUkXYwzRSCgn5YslSGOq5s3+UvMn0pDwiwAVlWsAtPs8ioKmxjpTrQdoLZ5I4LO1G/HZ2o0oLMjHxePPxYSLxmFgP/2vhZEVBRu37MDSVWvxxfrNOSt04nA4EYmEkcroVDQm4d+fdMW3J9VoFo8ecv1nFxSk3PkDEhwOp6bxMMawdccebN2xB3NeehPjxozEhIvG4pwRQ2AVINnf/dV+LF31BVau+TKjBatGE4tFcnl2QV8AlADwpDDWL1fPFY/HEAk3mW49wJkaGpvwweIV+GDxChQXFWLE0IEYNXwQRg4dhNKSbrzDA2MM+w4cxubtu7B5225s3bkHkYgme4E7JFkssDscKe9D3vSVC+t352HMQG3OXOfd/3/6pRPrd6W+AM/ucOR0xC0Wj2PlmvVYuWY9XC4nhg8egJHDBmLksMHoU1mui0Wxx2pOYPP2Xdi0dRe2bN+N2voG3iHpRiIe03LR31kYIHyhCeETAMZYz1w+XzjUCJvNbsr1AG2prW/AijXrsWLNegBAafeuGDlsMEYMHYDelRUo71ECp0PbVddNoTAOHzmGr/YdxOZtu7Blxx7d3A3ZbHbIciLlhunfnxZjSGUUeS71GzKe0331TRbMeS/1xNlitcJm47daPxKJYt3GrVi3cSsAoLAgHyOGDMDIYYPQr08lKspKNV8TE43FUX20BvsPHsaW7XuwedtOHKNyx21SFFnrRX9tqcj1E6rNCAlAzm85mxrrTL0eoCPHjp/EkuWfYcnyzwAk51i7d+2C8rJS9CwrRUV5Kcp7lKAgPw95bhdcTifcLiecTsdZd1iKoiASiSIcjSb/DEdR19CAQ9XHcPjI6Y/6Bn109u1xOFyIhkNI5byKxrAFb6wsgmei+g09zymA59/LQ0MotTtoCRIcDn3NxTc0NmH12o1YvXbjqc8VFeajoqz01EfP8lJ0KSyE2+2Ey+WE25n888xdNIwxRKMxhCNRRKJRhMIRNDaFUH20Boerj+HQkWOoPnIMx0/WGeooXq0wxtJacKsi/sOdWRI+AQBynwCYfT1AOhhjqDlRi5oTtdi0dWe7j5MkCU6nA26X81THb5QqZZIkwe5wIhZLrZFavTUf44aEMbRS3UaNV2eydqcDyzakPpdvdzh1MdzemfqGJtQ3NGH7rq86fJzTYT+VCIQjUUSjqh9MY2o5nvdvJfd9j9qMcAvLpZB9PB5DU6M5K7hpgTGGSCSKk7X1qKtvNEzn38Jqs6W1le2VxV0RS6j79uTRRkZiEv6+IPWhf6vVBqvNAPclrURjcdTVN+JkbT0ikSh1/iqKxaI5nfc/g/B3gJQAZCEWDSMcMt7RwUQb6dzZHq+3YuEadeuM8Oh3XlyUh5pUTvrD6ZESQlIRj8dUP+UvTZQA8CYBXXg+fyTchGhEm1XbxFgkKb257SXrC7D/mHqLTXN957kjjZP+gORaCRGG/gl/iUQcidwv+juT8MeoCp8AQOL/Swg1NfBahEIEk87q9pYTA2WVDjNT6zqpSOekPyC5W8IiaHEpkluynNDqiN900QiADhTyDgBI7gzgsA2FCCg5FZDaW+/QcTsWr1dnKkBRcjcCUPVpHg6keNKfJFlo6J+kRJFlPd1scR19VoPQCcC0mbO6MKafnQxNDbW856SIIBzO1IfG311ThKO12b/MFYXlZB3A/qNWzF+a+h75dH4WxLwURUFUP50/ANimzZwldBIgdAIAhhLeIbTGGENDQy3PValEEBaLJeViUgkZeHmxOjuOZI1HARgDnnmzAIkU3wI2u8Pwp02S7DGmIBZNrax2TumsD0qX2O88xrrr7QXBFAUN9SdTPgSGmJfd7kj5jPvdhx1YsTn7E6+1ngZ4d7UrrWN+7VRRk3QiecAPr73+nerOO4BsCJ0AKIzpMvtSFBkNdScgy+Y8kYukLp3Dbt5c2QW1TdktlJNl7RrRY7UWvPRRXsqP1/qgHyI+RVGaT/fL4QrW9FACwA1juj2gXlEUNNSdQILWBJAOJA8MSq0jjDSfGJgNLUcAnl1QgEiKJ/3ZHU4qpU06pCgyYtGwXu/8Wwi9gEXodyBjTNc/fMYYGutP6mXLCtEpm82e8lTApq9c+HJP6nfZZ9JqDcDSDamf9Gex8D3oh+ifLCcQjei+8wcoAeBHAdP9GCJjDI0NtYhGw7xDITrmcLogIbW751c/KUY4mtlbV4sRgIaQhOffTa3crwSJVv2TDsmJuJ62+nWIAUIvYhE6AQDTfwLQItRYj0hY36fWEX7SKYPbGLZi0cbeGT2PFmsAXltegYZQak2JKAf9ED4S8RhiYo2YUgLAC2NMqB9+ONSIUFMD7zCITqVyYJDVakPPyl7Ye3IQDpxMf/2R2tUAtx/qiu1H+qFnZa+UYjfaQT9EPfFYVMRiakL1QWcSOgGAgD/8aCSEpkY655u0raM7ZJfLjV59+8Cdl1wDsGjzUCSU9HYFKCqOAMQSVsxfPQAA4M7LQ6++feBytb0ulw76IR2JxSKiLpgWrg9qTegEgAk0BdBaLBpBQ/0JyFQwiJwh2VGePUdeVFyMnr16w2Y9vXiuPuzGqt0D0rq+whgSKiUB763rg9qm029Bm9WOnr16o6j47OM57HTQD2kDY8ltfnJC2C3TlABwJOwPX04k0FB3XJjFLiR3rK0ODLJIFvQoL0dpaVlzFj3dAAAgAElEQVSbHei6r/vgWH16ZwXE49nPA+w7VoiVOyrO+rwkSSgtLUOP8nJYms87sNnssNJBP+QMciKBSDgMRdHtHv9UCNsHAYInAKKOALRgjKGpsQ6hxnqaEiDfYHc44XQ6UdmnDwoL2y83zhjw4ZbhUFjqd9fxRHYNrqxIeG3VwA7PFSgs7ILKPn3gdDpp6J+cJRaLIhaLQG+VXDMg9Itb6AQAgv/wW0SjYaocSL6hoLAQg4aNSKlaXk1DAdZ93Tfla2c7ArB4Uy8creu8FoHD4cSgYSNQUKiLAzuJDjClZchfyPn+ttAIAD9i7QLoiCwn0FB3ovnAC2JmJT16oLJ3H9jtDjhcqe2ZX7V7AGpDqe3Fjycyv+s6WpeHxZt6pfRYh8sFu92Byt59UNKjR8bPSYxBTiQQiQg/5H8mofsgsRMAHR0FrIbklEA9mmhKwJTsdjt69+2H7iWlpz7ndLpSmj+XFQkfbR2W0vMoSmYLARkDXls1ELLS+XSD1WqFs1XBn+4lpejdtx/sdqoAaD4MsVjEKEP+ZxK6DxI7AQAMM47UWiwaRn3dcRH3xJIMSJKE7iUl6DdwEPLyz76Ld+XlIZUigQdPFGPzwdTuzjOZBli5owL7jqUwnC81x3yGvPx89Bs4CN1LSmhHgEnIsoxIOCzyKv/OCN0HiZ4AGLaHVGQZjfUn0dRQS0cLG1iyUxyIkh5lsLRzOI7FYoWznf31Z/p0+0A0RTufNkg3AahtcuK9dX1SeqzT5W73bAOLxYKSHmXoN3Bgm8kOMQbGGGLRSPNhPoYa8j+T0H2Q6AmAUDUjMxGLRVFfe5zKCBuMzWZDz1690Ltvv5QW+jkczpSq6MVlG5ZsHdL549LcCTB/9QDEEp1PRVhttpS/n959+6Fnr16wUXVAQ0nEY4iEQ2ZZ1Cx0HyR6AiB09pUqxhjCoUbU1x5HgqYFBCeha7fu6D9oMAqL2t/e1xa3Oy+lofPdx0qx62hZh49JZyHgur2l2H6o82OIJUmC253eSYWFRV3Qf9BgdO3WHSnNcxDdUhQZkUioeerScHP97RG6QRY7AZDE/uGnS5YTaKg/iabGOqOtpDUFd14e+g0YkCyS085wf0ckiwVOd2pTAUu2DkEk0f6CO0VhiMY6fw01Re14+/N+KT2n0+2GlMH3ZbEkix31GzDgVJljIg7Gkov8opEwmPnaJaH7ILETAMF/+JmKRSOor61BNBKCiTJtYVmtVpT3rESffv3hTHFbX3vsdgdsKaykD8UcWL5jcIePiUQ6X1vy9uf90BTt/Plsdjvs9ux2RDldLvTp1x/lPSupcqAgEom46KV8syV0HyT05JvFYu0lq328mSAYYwg1NSASboLLnQ+H000rq3XGarWiuGtXdO1eomqH5nLnoUmuB1M6Tv42H6zA0Ipq9Op6os1/j0RldEH7nfuOQ8VYt7e03X9vIVkkuNIc+u9Il+JiFBQW4uTxGtSePElnZuhQIhFHIh4z/XZlCcjsXG6dkET8BU6bOasLY/i9LMcfisei1OshOTzscuXB6Uptnphox263o2v37uhS3DWjof5UJBJxhJs6Xxha5A5jxkVr4LS1vVupe1cnnI6zYwxFbXhy4bnfOOynPe78/FNnF6hNURTU1Z7EyePHEY8LveNKfIwlO/5E3PQdfysMkP4hSfhh1dzZdbyDSZdwCcC0e2d5GNgfAJTLcgLxmNCLMFUnSRa43HlwutyQJNFneMTicrvRrXt3FBYVIRcL2iLhEOKxzkcg+3Q/iclj10PC2aNlLpcV3bp8c+heViT8Y9FI7D3a+SFDdodD1bv/9jE01NfjxPHjiISpWmYuMcYgU8ffmWoJ0g+q5s0O8g4kHcIkANNmzipijM0DcGvL52RZRjxGp+m1RZIkOF15cLnyMlqYRVJXUFiIbt1Lcr6AjTGGUGNDSgtC+5WewHUjt8Bl/2bCLElAaXcXbNZkwtIQduCV5YOxq7rzHQoWiwV5BYU5H3EKh0I4cbwGjQ0NOX1es2Gt7vg7PPmJtPaWJEn3Vs2dXc87kFQIkQBMu3fWOQzsdQDfWNXEZAXRGN0NdESSJDic7mRJWY2Gac1IkiQUFRejW7fucDj5nUklywmEGhtTemyeM44LBnyFIWVHvpEI5LttsNjzsW5vKZZsrkQomtrSoLyCAlit/JYRxaJRnDhxHPW1tXRnqiJFUU7d8ZOOSZDAzl6IvVOCdFvVvNkbecSUDt0nAM1D/s8COKtsmKLIiEVpBCBVVqsN3Up6gDHQwqoM2Ww2dCnuiq7duqVUmCcXopEwYtHUp8IsEkNxfgiFrggkSUJ92Inapry0jhR2OJ0pVyfUmpxI4OSJE6irPYmEeVejZ8Vmt8Nus+HkyeNm3MqnhSYJ0sN6nxLQbQIwbeYsK2P4A8Aeb/dBioIInZ6XloGDh8PldiMajSIcCiEcDtPdUyccDgcKCotQUFSYdqGbXGlqbICSo6TOYrUiv0CfR/yGwyE01jegsaEesRTWR5iZxWJBYVERiroUIy8/H+FQCNu36P6mVVckdLYRW/qLJOEHVXNn6/KOS5cJwLSZs5yMsSoAkzp6HGOseS88SYXVYsWwUed+43OMMUTCYYTCYUQjNJrSwulyobCwCAVFRXByHOJPlaLIaGps0L4shATkFxS2W+tfT6LRKBrr69HQUE+v7VMk5Bfko6hLcqvlmbtUNq77nEYH1bdQkqRpVXNn627Fuu4SgGkzZ+UzxhYAmJjK46lGfuoKCrugb/+B7f67IsuIRqOnPszVEEhw57lRWFSEgsIiIY+tjUWjiEa0HRFzutxc1zxkKh6Po7GhHg319QiHwjBTAS273Y68/Pzmj4IOz17Ys3M76utqcxidaSyWJOmWqrmzddVh6SoBSO7vZ+8BuCjVr4mEqRpeqnpU9ERpaXnKj08kEslOpfnDaOWHrVYr3Hl5KCgsREFhIdcFbWoJNTVqVpXNarMhL79Ak2vnkiwn0NjQgMaGBoRDIcMlujabLdnZ5yU7fbsj9QqNR6oP4fCB/RpGZ2qrJEm6QU/1AnSTAEybOauEMfYhgDHpfF00YvjjJlXTf9AQ5OVl3oAnEolTyUBMsITAbnfA6XLB5XLB2fwh4l1+ZxRFQaixQfV1HZIkIa/g7CFjI4jH44hGIohGIog0/xkX6NAtq9UGd14e8vLzkZ+fn9UITVNjA3Zu26JidEbW+QqANqyXJOnaqrmzazQIKG26SACmzfxuEWPKCgAj0/1aSgBSI0kWDB81WtXiQIqiwGqzQZYVxGLJpCAWiyEe41ciVJIkOJ3OU528y+WG0+UUYs5aLfF4DJGQumtjXHl5Wdf6F4miyIhGoohEwqeSg2g0yvV1bXc44HA44HA64XA4T/1dzTLTjCnYsPYLalO1tVmSLJdUzf0b91oB3BOA2x943ConEu8D7OpMvj4WjUBRjDWEp4W8vAL0H9T5OfHpcuflt3E4DUMsFkc8FkUsGkMsFoOiyFAU5Zsf8um/t5dJW6xWWC0WWKxWWCwWWK1WWCxWWK0tn2v+u8UKh9MBh8NJpZABhENNSKhUOtdmt8Odd9YuXNNJnnqXfE0rigxZVpKva/n032W5+XUuy5Cb/2ybBIvFkvywWk7//dSHtbmDd8DucMLhsCNXxyXv3LYluaCUaEj6yGqzXf/a83/h2nlxn/RUZPnZTDt/ANTYpyivQJu52zaKYACQko2Xw4FUp4wVRQFrSQYkqbmjN95wc66kemBQZ9Q+6EdkydElF5zO9E50VBQluc6AMVgsFkjNnbxeFRQWUgKgOXZ1su/Dt3hGwfVVeNt93/sxY8qD2V2FEoBU5OVrdAen0gCSxWKB1WaD3eGA3W7XdQMpAklSp+N2uelwqWxZLBbY7XbYHQ5YbTbdv7b1WuPBaBhTHrztvu/9mGcM3F6Jt9//2O2KIv8m2+tQ25Qal0ZV29oeASB6YLPZ01oBfia7w6HZKX9Ev2jEJ3cURf7N7fc/djuv5+eSANx+/2NjZFmeq8rzUwbQKUmyaLeASweLSEn7nC53RnecFotFN6V+SW45HA46STR3LLIsz739/sfS2v2m2pPn+gmn3P1IviwnXgGYKq2LJJlndXemHFncBXaGun99kyQJrgxOKXTl0dC/mYlQ/ZI/td4fzC3LiVem3P1Izlfa5jwBcDjdfwWg2nJ0aqM6Z09z0VJaaARA96xWG5yu1F8DTpfLEEWRSOYcabxezEvVtm9Ic9+YUzlNADxe33Sr1fqAmteku5TOObUcAaAEQAgOpwsud+eDbi63Gw4tE0YiBBoByL3/396dR8l11Qce/973XlX1JsmLbMk7bluWzbAbG4PZwh7LgCG0lPQJMFKAPkNCFghNhsCcSTIMRDMQM6QTZBgbLCxoBI1ZZEg8YY1ZAma1kW3Z7U3WYllbr7W+O39Utd1q91Jdde+7b/l9ztGxLXfX+9XS/fu9u/yu7/ub+wcGN0V5zcgKgP6BwfOBbcrwClilFCzjGNMsSmLvdmFeLl+gs7sbb57GMZ7v09ndTS4vnxXBsrc6Zo6F+55GbtzWyJWRiKQA6B8YzAGfB1aB+bt25UkBsBibBYCMACRLEOTo7llBz8pVdHZ309ndTc/KVXT3rJAV/+Jxy5kyyiTDKWdWTlwFfL6RM62LagTgr4HnzfyH6RWmMg2wuLzNuzopABJJKUUQ5AiCnPz8iCeRUcNozcmJz6OeM62zXgD0Dwz2Au+b/XfGpwFi3ljDJaWU1R7uoRQAQqSOtNSO1jw57H2N3GlVFJnzWuCE8STP9BSA7FldUC6Xt/qDLIeGCJE+Sim7I4eJZ/Z36jw5sYN67rTKaubsHxjcALx27t+bnwIw+nCpYntFd7u95oUQ8STrABZj+rjteXPiaxs51BprBUD/wGAB+Ph8/8/0oj1pBrQwm02AZsgogBDpI+sAFhPZQvaPN3KpFTZHAN4LXDDf/5ARgOhE8UMcyiiAEKkjWwEXE8kIANRz6HuNXmwWKwVA/8DgecD7F/r/9Tlpc1lbKSULVhYQRQEgIwBCpI9MAURlyfz1/kZONc7WCMA/AIu2HTO/EFCmAeaTz0VQAMgIgBCpI4sAF2J9AeBcndRzqnHGC4D+gcFXAW9Y6utMb93zpBnQvDzf/g4JGQEQIn38eTpGCjA+/N9cLnxDI7caZTQ79A8M5oGmDjQw3g0wgkSXRPO1fTUtDKUAECJtovjdkUj2ugAu5RONHGuM6SO/3k2TJ/2ZHgHw8agYfcR08CLokSDtgO0Kw5BKuUStViMMaygUnu/j+wG5vN0+D4vRWlMpl6nVqoS1GhqN5/n4vk8uX8CTBl2JJu/f/JQ2OwawjFx4EfUc+xFT1zb2DvcPDJ4NfKDZrzfevMfzMF6aJZynvEiSg0wB2FMul5iaGKdcLlGrVdFaE+qQarVCqTTN1OQ4tWo18rhq1SpTk+OUStNUqxVCHaK1plarnhCzSC6llBQB8zB9u7PMXPiBRq41wuS7+1Ggu+kLW/hgyU6AE0XVIlkWAdpRnJ6iVJxGL/IrJwxDpqcmKJeiS7blUonpqYlFp340mlJxmuL0VGRxCfOkALBvma9xN/Vca+baJh6kf2DwZcDG5XyPja17nidzVrNFNYcXygiAcdVKhUql3NTXaqBUmo6kCCiXSpRK003fBVUqZaoVmZxLKlkHMJfp3Wst5cGNjZzbNlPlXUsViemELYcCnSiynRFa1gGYpLWmWFz+nbPtImAm+S9XsTgln4+EkhEAu9rIgUZGAdp+dxtbE57V0sVNLwSUKYAT+BGOiMg6AHNqtVrLCdNWEdBq8gcaawNqhiMSUZCtgCdShlcAtJEDn2ViW6CJDNxym0IZAbAryikRaQdsTthmsjRdBLST/Ge0+5yEGzKteiLTv+XafH3bbhHcVsbsHxh8NvCKVr/feMJWSo4GniXK3ghhKL/gTTHxWpoqAkwkf5DPR1JF0Ugsy9rMga9o5OCWtfvutlWBKAsJWxatPMGPcERE7vDMMXXX1W4RYCr5g9xJJlWU04hZo8xs024rB7ecIfoHBp/CMlf+zxuA8ZbAUrHO8CI8H0G6AZpjct611SLAZPIHmUtOKinc7DGUqzY2cnFrMbRx4b8A2v50mP6AyQf2CVEO38kIgDme7xsdGVtuEWA6+SvlychcQskUgD2GcpVPPRe3FkMr39Q/MHgK8EetXvSEAAx/wGxMKyRVlIsitday1csQpRQdHYseprlszRYBppM/QEdHpzTpSii5obLHYO77o0ZOXn4MLV7wnSyj69+iAVj4gMmHti7q6l1GAcwJcjlyOaPnfixZBNhI/rlcniCXM/qYIjoyAjDDfAFrME91U8/Jy49hud/QPzDYAbyrlYstGIThO3ZZuFKnI56Xl5XeZnV0dhEEZpPnQkWAjeQfBDk6OruMPqaIVtS/Q+LKdPq3cEjbuxq5eXlxtHChtwKnt/B9C1KG5wdVVB3wYi6sRfvDK81ezOvs6rZeBNhK/p1dRgYJhUPyM1232HkcrTCd86jn5Lcu95uWVQD0Dwx6wHuWe5ElgzA8V608DyUnA0Y+JC87AeywWQRI8heLkWk9OyztVntPI0c3H8cyL3ANsG6Z37N0EBaG7GXbEdQiHpKXKQB7bBUBkvzFYmQEwM4h85bWqa2jnqObj2OZF2i79eC8QVi4Y1d+YPTxkqgW8RSADmUngE02igCTJPmnjxQA5tv/KpTNfjXLytFNR9E/MPgi4Iplh9NsIIbv2P3Aw07tlhzawR25DBnaFdciQJJ/OsmoHsbTiOWeGFc0cnVzsSzjga3c/c/wTd+xa6tVViJEPQUA8gsjCnErAiT5p5eMAGB8CMB4rnuypnN1Uxmyf2DwfODqlsNpJhALVVHWu49FPQUAUJOFgJGISxEgyT/dpAAwL4K8dHUjZy8dS5MP+BYsj6crZf6OPesLAV0Mx8sUQHRcFwGS/NNPfp7N8jwjBwAtRVHP2UtqNuO+ufVYmucZHhqpn7aU3WkAF8Px8gsjWq6KAEn+2SAjAGaZznGLaCpnL5kd+wcGXwhc0HY4TbBxxx7hCx479f78Ee8E0FqKgIhFXQRI8s8GrcOM7+oxf6ce4aj0BY3cvahmbo+bGkowwfN849sBfVkIGPk1q7Vq5NfMuqiKAEn+2SF3/4a7/6GiPqdmydy9aHZs9BbeaCycJpheIOH55ouKJIm6HTBArSoFgAu2iwBJ/tkiBYBZDhalb1zqfIClbo9fD6wyF8/SbGyR8ILsTgO4GI6vyQiAM7aKAEn+2SNTeWZFsP1vrlXUc/iClioAln24QLtsVEm+7367lCsupgB0qKUfgEOmiwBJ/tmU7REAC8f/utmVtmgOX7AA6B8YPB14lfFwlmBjO6DnqczuBnB1QI9MA7hlqgiQ5J9d2T7cy+z8f0Tb/+bzqkYun9diWfF1gJOSxcbK/SCjuwFcrAEAKQDioN0iQJJ/tmV1BMDK4T/u8o9PPZfPa7ECYNG5A5usbAfMZbMpULVWcXRdKQDioNUiQJK/qFbd/O5wTVuoABw3pVswl89bAPQPDHYDr7AWzhJsbAdUeFFvwYiFcrHk5Lr1dQBZHkKMj+UWAZL8BUCpWHQdggPKeO9/B9v/5npFI6c/yUIjAK8CFt0+YJtvYeV+Fs8GcPlDLNMA8dHZ1U2h0LloYa1QFAqdkvwFAMXpadchOGC+8ZGNXLZMHSywnm+hAsDZ8P8M38JWJgfbMJwruiwAZBogVvKFAl09PeRy+cYoW32+0/N8crk8XT095AsF12GKmMhmAWCejVzWgnlz+pMKgP6BQR/LJ/81w/M847sB6jsMslUE1GoVZ/PxMgIQP57n09HZRXfPCnpWrKJnxSq6e1bQ0dnlephSxEi1Ws3sGgCTbOSxFl3dyO0nmC+yK4FT7cezNBv794NctgoAgFLRTSUfhqGsA4gzpep/hJijOD3lOoRUiFEPmlOp5/YTzFcAXGM/luZYWQfg+ZnrCeB0HYBMAwiROEVHNw1pE4P5/9meNA0wX3SvjiCQpiil8P3AeBLJBTnKFTer411wvRAwl8sbfcxqtUK1UqFWq6HDGkp5eL6PHwTk8+7msMMwpFIuUavVHm+j6vk+vu+TzxdQ8RgKjD0dhpQXeB1z+YLTIdVyuUStWiWs1dA6RHn1uIJczsmxzLZkbf5fYX75n+8Hrpr/LOQ1wHtm/4Wafdxj/8DgauBR7PRCaEmtVqVcMp3AFMWpSVDZOOqyu3sFT7lgnZNrK6XoWWnmOAmtNaXiNJVKecGv8Rtz3FHv+KiUS5SKRfQCv0aUqq+wz+XNFkNpUymXKZWmFzyGVqEodHSQi7jQC2s1itNTi7bWzuXyFDo64/ZLvyX33r2bifEx12FEQ9OYCjObD/KFjrgtPNfA6Tu2bX1s5i/mltIvIkbJHxpVlPGQNEEuPdX6UlzuBNBaG1lMpLVmanJi0eQP9bMPpiYnqFaiW8A0PTVJsTi9YPKHevzF4hQl48VsepRKRYrFqUXPoNdoisVppqcmI4urWqkwNTmx5LkalUqZqcmJReNPikyNAFhI/goVt+QP9dz+otl/MbcAeEl0sTTPxjxKTLZmRMLlTgDASDIul4pNHzCk0RSnpyIpAqanJpdV4FRKxcy2WF1MrVajsoziqFqtRFIEVCsVitNTixZ3s4VhzcKIZbRkB0D7Yjb3P9sJOX5uAfDiCANpmo1krRSZ2hLoch1Au4m4VqtRKS9vzUYURcBykz/U7zNKRVlhPVepOLXsezDbRcByk/+MmXUgSZWpu3/ATvOf2N5gnpDjHy8A+gcGVwHPjDycJnieh2dh5X6WtgS6LADanQaoVSst/YjaLAJaSf4zarVaKoaJTdFat5wwbRUBrSZ/qKeTWoLvoGUHQHs8FZu9//N5ZiPXAyeOALyQxQ8HcspGReV5fmaan7jqBTCjnSTc7ND/fGwUAe0k/xlJvkM0rd3XwnQR0E7yn9HOZ9Y16QHQnhjf/UM9x79w9n/MiOXw/wxbcyq5eL9Zxrg+2KO9AqC9u2WTRYCJ5A+gE5wgTDPxWpgqAkwkf2j/M+tSVqYAbK12j/H8/4zHc/3cEYDYmukJYPxx/WyMAhQdL0xqZxrAxHCaiSLAVPIHMvGZa5ap16LdIsBU8gczn1lXsjIFYKNEi+He//mcOALQPzCogGc4C6dJgeGGMo8/bgZGAWrVivOufK0mX1N7+tspAkwmf0U2T6ZciOf7xu7GWi0CTCZ/SO77W6tWI91Cmza2cpRhz2jk/MdHAM4DetzF05z6wQrmf7C8rIwCJHQdQBDkjPWCaKUIMJn8oT5HmIC7hMgopYzOmy63CDCd/BUqsTcV0zL/37L6mrJEjPz0UM/5jxcAT3MXy/KYbis7I6k/sMsxOT7h9PqtTgN4nmf0mNrlFAGmk3+9k12nscdLi0JHp9GGX80WAaaTP9SPXU5IIniSibGMdP+zwFZusuRp8EQB8HSHgSyLrbv1LIwCxKG1Z6ujAKbbajZTBJhO/gCFjo7EJgebPM+j0NFh9DGXKgJsJH/fD8gXzD6PKI2NHXcdQiJ5np+0aZ+nQwJHAABrbXzTPgowPT3ptCMgtLcboLOrG99gkbZYEVC0kPzzheh72CdJLl8wnjyr1Ur93I+5f28j+Xs+nV3dxh4vatVqlalJt6OESZXA1vInjAAkqgCor7Q0fxeVhVGAyfFxp9dvZzeAUorO7h7rRUBxapKKheRfSPCdYVQKhQ7jRUBlThFgLfl39yR6bce43P23RCkvjn3/l/I0AP+e/VMB8A9AojKfUsrKqnbf85zfJdvk+T4rV57kOoyW58uUUgS5PLVq1Wg3vVq1iuf5lMtFSf6OBY191CZ/vsMwbPQbUJL8F3Do4AGmp9K7CNDWu5N3fER1i07+8jdu/YgHrAMStXoB6s0WrPzAeV7cOzm1ZWLM7QgA1O/AwjBs+fttjQRMT09SMbwFSpJ/a6yMBFQqTE9PSvJfwPjxdI8A2Nj3X9/Bkri7f6jn/HUecK7rSFoVBBZ3BOjk/0DPp1otO28LDCz7cJ+5bBQBpknyb4+NIsCkNCX/4vTUkkdtJ5bFpoy2clBEzvWANa6jaFWQM7c/fDalFLl8ekcBxmOwG6BSLrc9hB/nIkCSvxlxLQLSlPwBxtJ892/pLVKoJC7+m21NogsAsLf60g9yePE9G6ktkzEoALTWRu444lgESPI3K25FQNqSP8D42DHXIVihbN79Jzv5QxoKgPp8vZ0fxCCf6OGdBU1OThLq1ufgTamU2psGmBGnIkCSvx1xKQLSmPzDMGTCcZMwW+zN5JrtXunIGg843XUU7aivCrfzRqR1W6DWIZMT7hcDhmForO94HIoASf52uS4C0pj8od4gTMfghiBJglwq2nmfnvgRAKgf6WvrzcjlO7C3gcSdyRjsBgAot7kYcDaXRYAk/2i4KgLSmvwhzav/7bxXSqm0HCOf/CkAABp7wy09dNJ6PDdlfCIeP/S1apVarf3z4Ge4KAIk+Ucr6iIgzckfYCyl8/+2lv8HuXw9MSRfSgoA6lv3bDVj8IMAT6VrKqBcKrW9Fc8U03FEWQRI8ncjqiIg7cm/XCpRKhZdh2GWxYV/nuelqWX8Gg9ITXPyXM7eU8kV0jcVMOG4LfCMSqVsfA4yiiJAkr9btouAtCd/SGn7X4vvl80c40DBA1LT99bzfWs9metTAamp/AAYn3C/HRAADeWy+SYkNosASf7xYKsIyELyh7QO/9sZAvD9IGkn/i2l6gHmJmBjIGdx654f5FK1K2BybIxaGI+3vz4NYP4H10YRIMk/XkwXAVlJ/rVaLcULAM2zmVscqaWuAFDKs9qeMU27AkIdcuzoYddhAKBDTaVstg//DJNFgCT/eDJVBGQl+QMcOXyorTM54sfeexYEeSsn0DqWvgIA6kP1tn6A07Yr4EBqTpQAAB6fSURBVOjhx1yH8LhSaRoMnvA3m4kiQJJ/vLVbBGQp+QMcPvSo6xAMs/e7I23Tvw3pLABsbguExq6A5J3/PK9SscjUVDy6gOlQG+0LMFc7RYAk/2RotQjIWvKfnBinOO3+ULAkSNG2v7lSWgBgd1sg1EcB0jIkdCRGowDlUtFqV7JWigBJ/smy3CIga8kf0nj3b0fKtv3NVfOAlJ4BaXfLRv3EwAJpWA8wfuwYtVo8NoNojfV9yTNFQD5fWPTd85RHZ2e3JP8EKhQ66OzsxlukSFdAPl/IXPKvVascO3rEdRiJkLJtf3OVPeBh11HYYnNbINSrwzTMDcVpMSDUjwoODXYHnI9SikJHJ53dPeRyeTzPRzX+3vcD8vkCXT0r0nDiV2YFuRxdPSvI5wv4foBS9cPDPc8nl8vT2d1DoaMzU8kf6iN+6Vr8Z0cKt/3N9XAAjLqOwqZcvkA4XUPb2hsa5KiFIWFM7qBbdeTwY5y6Oj5NIYvFabq6e6xfx/cD/M6ZIlGThhEd8YSZQu8J8h7L8P/SFDMjvKk26gH3u47CJqUUuYLdN7KQgvUA5VKJycl4dAaE+jClqZMCm5ftxJAN2X6PJ8bHKRaTv/jP9ruYKxSyMDJ0v0fKRwCgcZfn2xvK1SlZDxCnLYEApRT8ohIiTg4fOug6BCMstvvH93NWp45jZDQTBQBAPm/3Lt3zPHKFZPcHGDt+jGot6rvuhYVhaHVboBBZUq1WOXb0qOsw2mP5Hkspj3z6Ov4tJP1TAI9TirzlOR3fC6x2IbRNa82xI/FaHVwuFtGWmgMJkSVHDh+yusU2EpZ/FeTzhbTu+Z/P/d6ObVuPAfFZAm6R5/vW93QGuZzV6Qbb4jYNoLWmXErZcaVCOJDsxX/2k3IQ5NK+6n+2wzu2bT02Myb+HaehRCiXL1hfsJfL5xN7aFC5XGIiLqcENpTLJdm2JEQbJsbHrPfXsMvurb9SXhZW/c/2XYCZTPhNd3FEz+YZ4jOiKDRsidsoAFoWBArRjscSffdvXxQ5IWZugRMLgMxMtNYb+Nidq1dKkS8kc2fA+NhxKpV4NYisVipUyvGKSYgkqFTKHJfOfwuqNwJL5s1aizSNm34PYMe2rfuBX7qMKGpBzv4wvVJeo7JMVhGgtebQwf2uw3iSUnFKpgKEWKYD+x6RhbQL8Dzf6sFxMfXLRs5ndtlzi6NgnIniDt3zPAoJ7BFw7OgRSjFbfKc1FKcmXYchRGKUikWOPHbIdRjLFs1vy5lR2sx5PNdnugCIas+n8n3y+WSNBGitefTAPtdhPEmtVpP1AEI0af++vQm8+1eRzEfb7g0TY/MWAD8B7o0+Frf8IBfJcY+e75FLWIOJsePHmI7hHXe5VKJaTfbZC0LYNjU1ybEjSdzhbT/9B0EOP73H/C7mXuq5HphVAOzYtrUG/K2LiFzL5QuRbNvzvaAUBPnvAYmZyD64P36jAADF6ckE3tkIEZ39exN10GuI5jtorLf+9Dw/a1v+ZvvbRq4HThwBANgB3B1tPPGQL3TYGw7S1MIwvKlaLV/89S986qVKee8hIbsuJifHY9cXAECHmuL0lOswhIil8bExxseOuw6jWRrUu77yuX96WbVavjgMw5vQWDkP/ImF2Zl0N/Uc/zg19y6qf2DwD+Z+UVboMGyclGUsN+uwVvt6pVL+4C07b/j17P9xVd/mv9I6/LCpC9nU2dlF77qLXYcxr0Jnp/UWz0IkzT2772BqMn7Td/NT7/nK9qGPzf6bq/o2PyOXy/+d5/uvxdjiKUVHRycqW1v+ZuvfsW3r52f/xXyvxDBwZzTxxIvyzFWHWuvvVMqlK7/2+etePzf5A9yy84aPKOX9JQmYDpienmLsWDwPESkVpwlrVm4WhEikY0ePJCX5h6D+dG7yB7hl5w2//trnr3t9pVy6UmttpFNtvtCR5eR/J/XcfoInjQAA9A8MvgnYGUFQsVStVKhUWpuKUkr9FM1fj2wfurWZr7+qb/MWrcNPArFekZIvFLjwoqfG8oxsz/fo7llBknZZCGGD1pq77vx1Etr+VkBt+cr2oc8188VvfPMfvxLFh7TWl7VysVyuQJCL9a9Y2/p2bNv6pbl/OW8BANA/MPhZ4C22o4qrcqlIrdb8SnPP83/s+f7f77z+2puXe60NfVuuCXVtB9C53O+N0plnncvJp652Hca8cvk8HZ1drsMQwqnDhx7l4Qdjf8DrlEJtHNk+tGu539i35c+vCWu194Vh7Ypmv8f3gyzP+wPcuGPb1rfO9z8WGw95B/BDO/HEX77Q0cTOAFXxPP+LuXzh8i9/9hPPbyX5A+zaef3NnvKvAuK32m6WRw8eIIzpcaKVcplqpeI6DCGcCcOQA/sfcR3GUo4p1KtbSf4AO6+/9uYvf/YTz8/lC5d7nv9FUIv+0Huen/Xk/0PquXxeC44AAPQPDJ4O/BQ413xc8ae1plScetJ2M4U6ojzv00Eu93+GP/0xYz9xG/q2XBrq2i3A6aYe07Q1Z5zJ6tPWug5jfgq6unvw/cB1JEJE7tED+9m39yHXYSzmgEK9ZmT70K9MPeCmt737rGql8qc6DN+m0afM/n9KKQodXbGctozIQ8BlO7ZtXfAkqEULAID+gcFnArcB3WZjS4YwDBud5zRKqbuU8j6RL3Tc8Pnr/peVdnQb+rZcFOrwVtCxLLp8L2DdU/8TfkyPO1ZK0dXTk9jjmIVoRa1W47e//uWypi0jdr9CvXJk+9B9Nh78D97x3s5yqbhZ6/BdWuuLQVHo6MzaIT+zTQJX7ti2ddFia8kCAKB/YPD1wBeBZLWyM+N4tVL5crVauXHkxn/8XhQX3NC35YxQh1+F1ha82Lb6tLWsOeNM12EsSHmK7u4VWV7xKzJm/96HORjD1t0NP1KoN4xsHzoYxcXe+JY/eUkQ5N4S5HK/B6yK4poxUwY27ti29atLfWFTBQBA/8Dgc4EvABe0F1sihMCtwGeBm3ds2xp58/mr+jbntOYzEPZHfe2leMqjd93FFDriO7fm+R5d3SuyPPwnMqI4Pc09u++I6UmZ6jNK8Y6RG4ciX6DTPzDYCVwDvBV4JYuveUuL+4Df37Ft68+a+eKmCwCA/oHBlcB1wKbWYou93dST/vYd27bGopy+qm/zoNbhh4BYTWx3dnZx/oXrY51gfd+ns7sn1jEK0Q6tNXt238lU/M7sqIJ671e2D13rOhCA/oHBM4E3Uy8GLnEcji3DwDt2bNva9GLyZRUAM/oHBt8OfJyYb1trggZuB74GfG2p+RJXNvRt2RDq2k3EbDjrtDVncPqaM1yHsaggCOjs7nEdhhBWHNi3lwP7Yrfy/6hC/f7I9qF/dR3IfBrr2l7X+HMpyW8gMg382Y5tWz+13G9sqQAA6B8YfBrwYWADyXoBi8C/UU/634jLnf5SNvRtWR/q8Oug17mOZYZSivMvXE9nzPffS48AkUZTU5Ps2X1n3A7FukuhXjuyfSgRJ8s2Rgaupl4MvByI77zmk2lgF/Bfd2zbekcrD9ByATCjf2BwHfDn1IdW4rpT4B7g+8A3gFt3bNuayFNkNmzcsjIMwy+CfrXrWGYUOjroXXcxXszP1c4XChQ6kj5gJURdGIbcs/sOitORL09azDeUUv0jNw6Nuw6kFf0Dg13U1wpcDbwYuMhtRAuapD5Vfe2ObVv3tPNAbRcAM/oHBk+m3nDgT4CzjTxoa8rAz6hvXbwN+OGObVsPOYzHuKv6Nv+Z1uH/BGJxW3vq6jWsPfMs12EsqdDRkfWmICIlHnn4IQ4d3O86jBmTjfn+f3YdiEn9A4OnAS8Armz8eS5ud8LtBf4RuG7Htq1GDmcxVgDM6B8Y9IFnUH/BXtD4c57RizzhMLCn8ecO6l2Pfrpj21brZ0q71pgSuAn0pa5jAXjKBRfRnYC59o7OLnL5+s9wZ77Mio4SPYUSPR1FegolytWAiVKB8WIH48UCk6UCtTDeoxtifr4X0l0osaKjxIrG+5sPqkyUCkwUOxrvc4HpcrJ2N0+Mj3Pv3b91HcaMnyjUHyZlyL8d/QODBeAy6jntacC6xp9TLV3yQeo57YfUb2Z/vWPbVqMnnxkvAObTmGe5EngO9S53p876c0rjnzOr3IvABDA+55+P8USy3wPsMVUFJdVVfZs9NH+jCd+H48OEcvkCF66/GE/FswGPpzTnrxnjqWcf4eKzj3NSVxHfa27b1FQ5zyNHT+KeA2vYc/B0Jkty/HAcdRdKrFvzKBetPchZJx+jK19u6vtqocfx6U7ue/Q07jmwhocOn0Ko47msKQxr3HXnbyiXnN/jVED9nVJ8aOTGoTjuP4xMY/R73Zw/q4EeYMWcf84MQVap38Aeafxz5s+jwM+B26JYnxZJAdCM/oHBbqC0Y9vW2LayiqsNfVsuD3W4HbTTOauTT1nNmWfHp4FhPqix/qxj9aR/1lE682Y+WjPFwN0H1nJ4Iq7LXrLh1J5J1q898HjSN6FYyXFvoxi49+DpVGrxKWoffvB+Dh9asLNrVHY37vp/7jqQpOkfGAyAwo5tW2OxbzM2BYBoz4aNWzp1qD+qCQdw2PDi3PMvYMUKt7sVfU9zxUUHeNnT99JdsNt/ZPf+tXxn98UcnYzFcozMOLl7it+55C4uOeOA1etMlfP8+z0X8vMHz3U+FTR2/Bije+52GUII6hNK8VcjNw7F/rxhsTQpAFJmQ9+W14Q6/L+gnfTqDYIcF66/xMmBPAp4xlMe49XPeohTeqL7/RSGip8/dC4/uHsdUwmbT06arnyZF63fw3POfQjPi+5317GpLr5710Xc+YibFti1apW77vw1FXcnXj6sUJtHtg/9m6sAhHlSAKTQho1bVoWhvg7CjS6uv+qkkzn73PMjvWbvmjE2XHo/Z53ibmStXA340b29/Oi+Xud3i2njeyHPv2CU5184Sj5wN0t44Pgqbr3zEh46fMrSX2zQg6P3cvTI4Uiv+QT1OaX445Ebh2J9XLlYPikAUmxD35b+UNc+QX2hZaTOOfd8Vp50ciTXevFT9/G7z36AuHT8ffjIyXz5Z5cyWZLRABO6C2V+77m3c84p8Vjzq7Xi27vX8+P7eiO53rEjh3lg1Mki+8cU6p0j24d2uri4sE8KgJTb0LflzFCHN4J+eZTX9f2ACy66mFzOXhIM/JA3Pu8+ntMbvzYPY9OdfPE/LuXg2ErXoSTampVjbLz8dlZ2xqrhDQC/2XsWu371dKujPeVymXt++xuq1chHPb7VGPK3u8hCOCUFQEZc1bf5TxvNgyJbtl7o6OD8C9fje+ZXUa/orPDml9zFuavj23SsUvP52i+eyV3717oOJZEuPuMAr3v2r8j5Rrc+G/XI0ZP40k8vZcLC1tBarcaeu+6MutvfRKOpzyejvKhwQwqADNnQt+WcUOuPQLgJiGRvU0/PSs49/wKjJ/KdtnKat7/iTlZ2NbfP27V/++3FkQ0Xp8UVF4zy8qfe5TqMpowXO7jpR88zuiVUa83onrsZHztu7DGXUAO1XcEHRrYPxe50IWGHFAAZtKFvy7NCHf7vqKYFTPYH6MxX+ePX/IbVK+M3JLyYkdufze598T45MS4uOXM/b7z0F67DWJYjk93c8IMXUKyY6ccV8X7/bynU4Mj2od9EdUERD1IAZNiGvi2vDnX496Cfaftaa844i9WnrWnrMTyl2fyy3aw7w0zDlyhVaj433nYFB47H6kTn2Fm76jhvufLHsR72X8joodV84SeXodvsIvjogf3s2/uQoagWdXsj8X87iouJ+JECQLChb/PmUOv/DtpqG79zzutl5aqTWv7+q597Py+8ODYHoCzbWLGDG75/pZX54jToKZTY/OLbWNmR3B4z/zF6PrfeeUnL33/86FHuv+8egxHN636F+uDI9qGbbF9IxJtsVhbs2nnDDUqpC5Xy3g9Yu71+5KEHmJ5q7STm517waKKTP8DKjiJvuux2gibPIMiSwAt502W3Jzr5A1zeez/PPGdvS987NTnJg/db3e53BNRfKqXWS/IXICMAYo4NG7ecpEP9N42WwsZvVYMgR++69cvaHriqq8R7X/8LAj8difO2PRfy3bvietS4Gy+9+B6uXJeOA+Wqocc/f/uljE03f/R0uVxmz+47bHX6K4L6R6X4HyM3DkW2qlDEnxQAYl4b+racF2q9FcI3YXikaLnbA/uefy+XXuD8ABRjKjWff/r2S5koylQAQE9HiXe+7LuJnPdfyK8fPpuv//IZTX2txe1+IagdCt4/sn3oYdMPLpJPpgDEvHbtvP7Bb37phk2e8p8H6rsmH7tULLL3gftppvhcc9IUz+lNT/IHyPk1Xrze+jxvYrx4/T2pSv4ATz/7EU5bsXSPCq01D9y3x0byv1WhLv3K9qE3S/IXC5ECQCxq187rf/bNL33mdzzlXw3ql6Yed2JijP2PLP176Xef/WBsWvya9Kxz9nJqz4TrMJw7tWeCZ7U4Zx5nSmledsnSJ/ftfegB03v9f6ZQr/7K9n961cj2IWM/ryKdZApALMuGvi0vCXX4btC/C7S96XnNmWexevX82wN714zxjlfe0e4lYuvuA2v40k8vdR2GU2+67HbWrz3oOgxrtv/wigUPDnr04H72PWxku18F+KpCXTuyfeg2Ew8oskEKANGSDX1bztZa/5km/M/A6nYea6HtgW97xZ1cuDbda5au++6LODS+wnUYTpy2Ypx3vPQHrsOw6v5Dq9nx48uf9PfHjh7hgfv2tPvwj4L6tIKhke1D+9p9MJE90R/aLlJh187r9wLvvapv8/uBzVrr/wL6Wa081t6H7uess89j1clP3Cl1Far0rkn/6aPrzziY2QJg/RnpvfOfcd7qw3TkKid0CDx6+DEeemC0nYf9Gaghpbhp5MYhK9sGRDZIASDacsvOGyrAdcB1G/q2vCjU4V+AvpplTA9ordn78APUwhqnnHoaAJecdQRPpX906qK1B/n3ey50HYYTF6V46H+GpzQXrnmUO/aeBcBjjx5k70MPtPJQFWBEoT4+sn3oRwZDFBkmBYAwZtfO638A/GBD35YzZ00PnN7s9+9/5GGqtSqnn34GTz3niLU44+SMVcdZ2VFkrNj8nvE0WNlR5IxV6Z7emXHR2oPcsfcsDux/hAOPLHvB44FZw/xyNK8wSgoAYdyundfvA953Vd/mDwBv1Vq/E/Szm/neQwf2E6gqF52ZvH7/rVq39iC3P3Ce6zAitS4Dd/8zLjjtEAf3PcCBfct6zj9tNO/5vAzzC1ukABDWNKYHPg18ekPflitDrf8CwtexxPTAeaccIJeSrn/NuCiDBUAWhv9n5IMaa7v3sn/pWbEyqC8r+PjI9qGfRBGbyDYpAEQkdu28/jbgtg19W9Zo9B9ord8A+vnMUwxc8pT0z/3PdvbJ2RntmJG153zRORV+sWfeAqACfB/UiIKdI9uHDkUcmsgwKQBEpHbtvP4gcC1w7YaNW07TWm/UWr8R9ItoFAOnrMxWAZAPqlCbQnudqDR2PZojH9TqzzlDTllxwohWGfgOqC8rxcjIjUOHHYUlMk4KAOHMri9efwgYAoY2bNxyktZ6k9b6905dqV9OxrpUFtQYhycq5PMFcvk8SqX36fcUkn3iXytWrwpD4FugvtRI+tlYASliTRoBidgp37fpbk+RqePyrrv1aYweXPn4f/tBQC6fJwhyqRsVOPfUI7z5BT92HUakQs3u/AXDT3UdhxCzyQiAiB1PsdZ1DFFb0Vk+4b9r1Sq1ahWlIMjl63+CdPy4rujI3giApzjDdQxCzJXecUaRSNXRTd3AyiW/MGVWzikAZmgNlXKZ6ckJJsaPUypOE9aSfXJeT0fJdQgunFQd3dTlOgghZkvHLYVIk1NdB+BCV2HpRXE61JRLJcqlEp7vk8vlyeVziVsv0JWbv9jJgNWAkdN/hDBBCgARN8nKZoYst+1xWKtRqk1TKk4nbr1AAkK0JZOfbRFfUgAIkXAnrBcIcvhBDj8I8DzJN0KIhUkBIERKaA2VSoVKpd45VnmKwA/wg6BREPiOIxRCxIkUAEKklA41lfDEgsBvFASBH+D5UhAIkWVSAAiRETrUVMMK1UqFEqCUqo8O+AF+4OP78utAiCyRn3ghMkprTbVSLwigvjjP8wOCRlHg+V7idhgIIZonBYAQAqivIZhZUPg4BZ7n43nerD8+qvHvQojkkgJACLEwXd9yOG/zIcXjBcFMcaBm/bcQIt6kABAiBp59/oF//sJ3Vu5SqEuU5/UqT53ted5aT3mrleetVB5dCuUrpTyllEIpz0MpPIUi4o31ChQKTb04qFVrWqNDQq01OtRa18JQT6H1mFYcArUfzUM6rI2GWt/1tFc8+FrgndEGLYSYSwoAIWJgZVdt7FMf+++7gF3L/d7+d7ynkO/oONlT3smeUicrpVZppVYqpXrQrFSKHqVUN9CDUl2guhS6E6U6ANBMA9MaPQVMKZjQmkmNnlCosfo/OQ5qDKWOaB0eK5dKxz7ziQ+11NO3Orrppa18nxDCLCkAhEi4Hdd9tAQcaPwRQoimyESdEEIIkUFSAAghhBAZJAWAEEIIkUFSAAghhBAZJAWAEEIIkUFSAAghhBAZJAWAEEIIkUFSAAghhBAZJAWAiJt5ms5nQpaed5ae62xZfd4ipqQAEHHzmOsAHDnkOoAIZem5zpbV5y1iSgoAEStB7/A0cNR1HA7scx1AhLL0XGccDnqHi66DEGI2KQBEHO13HYADWXrOWXquMx5xHYAQc0kBIOIoi3eIWXrOWXquM6QAELEjBYCIoywmiCw95yw91xlSAIjYkQJAxFHWEsSxxtqHTGg812Ou44jYXtcBCDGXFAAijr7nOoCIfd91AA5k7Tln7fmKBJACQMTRt4Ex10FE6KuuA3AgS8/5KPAD10EIMZcUACJ2gt7hMvBN13FEJAS+4ToIB75B/blnwS1B73DVdRBCzCUFgIirm10HEJEfB73Dj7oOImqN5/xj13FEJEujHSJBpAAQcXULUHYdRASynByy8NzLwLdcByHEfKQAELEU9A6PAf/iOg7LQmDEdRAOjZD+aYB/CXqHx10HIcR8pAAQcfY3gHYdhEU3Bb3D97oOwpXGc7/JdRwWaeqfYSFiSQoAEVtB7/DtwLDrOCwpAR90HUQMfJD6a5FGw43PsBCxJAWAiLu/Biqug7BgKOgdftB1EK41XoMh13FYUKH+2RUitqQAELEW9A6PAp90HYdhx4APuQ4iRj5E+joDfrLx2RUitqQAEEnwd6SrMdCHg97hI66DiIvGa/Fh13EYNEb9MytErEkBIGIv6B0+BLyFdCwI/Ffgo66DiKGPUn9tkk4Db2l8ZoWINSkARCIEvcNfJfmL5u4GNgW9wzXXgcRN4zXZRP01SrIPNj6rQsSe0joNN1UiK6qjm75APVEkzVHgeUHv8B7XgcRZdXTTOuAnwMmuY2nBcNA7/PuugxCiWTICIJJmM5C0rVVVYKMk/6U1XqON1F+zJLmd+mdTiMSQAkAkSuMs+WuA3a5jaVIFeFvQO/z/XAeSFI3X6m0kZ/vnbuCaxmdTiMSQAkAkTtA7vBe4AtjlOpYlPAa8Mugd/qzrQJKm8Zq9kvprGGe7gCsan0khEkUKAJFIjbMCXgdsdR3LAn4DXB70Dn/PdSBJ1XjtLqf+WsbRVuB1jc+iEIkjiwBF4lVHN/0h8Cmgw3UsDTcDbw56hydcB5IG1dFNPcB26lM/cVAE3h70Dn/OdSBCtENGAETiNX4RX4b7Y1f3AW8H3ijJ35zGa/lG6q/tPsfhfAu4TJK/SAMZARCpUh3d9DvUh2afG+FlxxvX/FjQOzwV4XUzpzq6qQt4NzAIrIjw0j8DBoPe4e9EeE0hrJICQKROdXSTor6V7EPABRYvVQG2AX8rnd+iVR3ddBrw34ABIGfxUvcB7wd2Br3D8stSpIoUACK1qqObfOBK6nPH1wDnG3jYInAr8BXg60HvcNxXqadadXTTauC1wBuo7xowsQ7kfurrOG4GbpPOjSKtpAAQmVEd3fRM6oXAVcBTgNMAtcS3TQL7gR9RTwj/EvQOT1oMU7SoOrqpG3g19ff4+cAZQPcS36aBQ8ADwC3AzUHv8K8shilEbEgBIDKrOropB6ylnijObPz7OPWEvw/YJ1u8kq06umkl9ff2TOrv8wrgAPX3dz9wIOgdTkrDISGMkgJACCGEyCDZBiiEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJkkBQAQgghRAZJASCEEEJk0P8HIGK4qJUDxrEAAAAASUVORK5CYII=" style="width: 16em;margin-left: 52em;margin-top: 63px;">
4
+ <div><h1 style="font-size: 90px;margin-top: -2em;margin-left: 401PX;">403</h1></div>
5
+ <div><h2 style="font-size: 54px;margin-left: 557px;margin-top: -140px;" >Forbidden</h2></div>
6
+ <div><h6 style="font-size: 21px;margin-left: 19em;margin-top: 7em;color: red;">Your IP has been blocked. Please Contact your Administrator.<h6></div>
7
+ <h6 style="font-size: 21px;margin-left:20em;">For more information please contact miniorange <a href="https://faq.miniorange.com/">FAQ'S</h6>
8
+ </div>
9
+ </div>
handler/mo-block.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
- ?>
3
- <div style='background-color: #d5e3d9; height:850px;' >
4
- <div style='height:250px;text-align:center; background-color: #3CB371; border-radius: 2px; padding:2%; '>
5
- <div class='mo2f_tamplate_layout' style='background-color: #ffffff;border-radius: 4px;box-shadow: 0 5px 15px rgba(0,0,0,.5); width:400px;height:500px; align-self: center; margin: 0 auto; ' >
6
- <img alt='logo' style='margin-left:10 ;
7
- margin-top:10px;width:40%;' src='https://auth.miniorange.com/moas/images/logo_large.png' />
8
- <div><hr></div>
9
- <b><p style='margin-left:10px; font-size:18px ;margin-top:0px;text-align:center' >
10
- <?php echo "Blocked"; ?>
11
- </p></b>
12
-
13
-
14
- <p style='margin-left: 10px;font-size:large; margin-top: 0px; '>
15
- <?php echo "Your IP has been blocked."; ?>
16
- </p>
17
-
18
- <p style='padding-left: 10px;font-size:large;margin-top: 0; margin-bottom: 10px'>
19
- <?php echo "Please Contact your Administrator"; ?>
20
- </p>
21
-
22
- <table style='margin-left:10px' >
23
-
24
- </table>
25
- <p style='margin-left:0px; font-size:1.5em; text-align:center;color:red'>403 Forbidden!</p>
26
- </div>
27
- </div>
28
- </div>
29
- <?php
30
- exit();
31
-
32
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
handler/mo-error.html ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <img src="data:image/jpeg;base64,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" style="margin-left: 5em;width: 12em;margin-top: 1px;">
2
+ <div>
3
+ <img src="data:image/jpeg;base64,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" style="width: 16em;margin-left: 52em;margin-top: 63px;">
4
+ <div>
5
+ <div><h1 style="font-size: 90px;margin-top: -2em;margin-left: 401PX;">403</h1></div>
6
+ <div><h2 style="font-size: 54px;margin-left: 557px;margin-top: -140px;" >Forbidden</h2></div>
7
+ <div><h6 style="font-size: 21px;margin-left: 23em;margin-top: 7em;color: red;">Your request was detected as suspicious.<h6></div>
8
+ <div><h6 style="font-size: 21px;margin-left: 17em;margin-top: -2em;color: red;">Please Contact Your Site Administrator if you feel the request is legitimate.<h6></div>
9
+ <h6 style="font-size: 21px;margin-left:20em;">For more information please contact miniorange <a href="https://faq.miniorange.com/">FAQ'S</h6>
10
+ </div>
11
+ </div>
handler/mo-error.php DELETED
@@ -1,34 +0,0 @@
1
- <?php
2
-
3
- ?>
4
- <div style='background-color: #d5e3d9; height:850px;' >
5
- <div style='height:250px;text-align:center; background-color: #3CB371; border-radius: 2px; padding:2%; '>
6
- <div class='mo2f_tamplate_layout' style='background-color: #ffffff;border-radius: 4px;box-shadow: 0 5px 15px rgba(0,0,0,.5); width:400px;height:500px; align-self: center; margin: 0 auto; ' >
7
- <img alt='logo' style='margin-left:10 ;
8
- margin-top:10px;width:40%;' src='https://auth.miniorange.com/moas/images/logo_large.png' />
9
- <div><hr></div>
10
- <b><p style='margin-left:10px; font-size:18px ;margin-top:0px;text-align:center' >
11
- Forbidden
12
-
13
- </p></b>
14
-
15
-
16
- <p style='margin-left: 10px;font-size:large; margin-top: 0px; '>
17
- Your request was detected as suspicious.
18
- </p>
19
-
20
- <p style='padding-left: 10px;font-size:large;margin-top: 0; margin-bottom: 10px'>
21
- Please Contact Your Site Administrator if you feel the request is legitimate.
22
- </p>
23
-
24
- <table style='margin-left:10px' >
25
-
26
- </table>
27
- <p style='margin-left:0px; font-size:1.5em; text-align:center;color:red'>403 Forbidden!</p>
28
- </div>
29
- </div>
30
- </div>
31
- <?php
32
- exit();
33
-
34
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
handler/mo-waf-plugin.php CHANGED
@@ -54,7 +54,8 @@
54
  else
55
  {
56
  header('HTTP/1.1 403 Forbidden');
57
- include_once("mo-block.php");
 
58
  }
59
  }
60
  $dir_name = dirname(__FILE__);
@@ -116,11 +117,12 @@
116
  $current_time = time();
117
  if($results[0]->time < $current_time-60)
118
  {
119
- $query = "insert into ".$wpdb->base_prefix."wpns_attack_logs values('".$ipaddress."','Rate Limit',".time().",'RLE');";
120
  $results = $wpdb->get_results($query);
121
  }
122
  header('HTTP/1.1 403 Forbidden');
123
- include_once("mo-error.php");
 
124
  }
125
  else
126
  {
@@ -129,7 +131,7 @@
129
  $current_time = time();
130
  if($results[0]->time < $current_time-60)
131
  {
132
- $query = "insert into ".$wpdb->base_prefix."wpns_attack_logs values('".$ipaddress."','Rate Limit',".time().",'RLE');";
133
  $results = $wpdb->get_results($query);
134
  }
135
  $query = 'select * from '.$wpdb->base_prefix.'mo2f_network_whitelisted_ips where ip_address="'.$ipaddress.'";';
@@ -144,7 +146,8 @@
144
  $results =$wpdb->get_results($query);
145
  }
146
  header('HTTP/1.1 403 Forbidden');
147
- include_once("mo-error.php");
 
148
  }
149
  }
150
  }
@@ -226,7 +229,7 @@
226
  $value = htmlspecialchars($value);
227
  $query = 'insert into '.$wpdb->base_prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
228
  $results = $wpdb->get_results($query);
229
- $query = "select count(*) as count from ".$wpdb->base_prefix."wpns_attack_logs where ip='".$ipaddress."' and input != 'RLE';";
230
  $results = $wpdb->get_results($query);
231
  if($results[0]->count>$limitAttack)
232
  {
@@ -243,7 +246,8 @@
243
  }
244
  }
245
  header('HTTP/1.1 403 Forbidden');
246
- include_once("mo-error.php");
 
247
  }
248
 
249
  }
@@ -294,7 +298,7 @@
294
  $value = htmlspecialchars($value);
295
  $query = 'insert into '.$wpdb->base_prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
296
  $results = $wpdb->get_results($query);
297
- $query = "select count(*) as count from ".$wpdb->base_prefix."wpns_attack_logs where ip='".$ipaddress."' and input != 'RLE';";
298
  $results = $wpdb->get_results($query);
299
 
300
  if($results[0]->count>$limitAttack)
@@ -312,7 +316,8 @@
312
  }
313
  }
314
  header('HTTP/1.1 403 Forbidden');
315
- include_once("mo-error.php");
 
316
  }
317
  }
318
  }
@@ -363,7 +368,7 @@
363
  $value = htmlspecialchars($value);
364
  $query = 'insert into '.$wpdb->base_prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
365
  $results = $wpdb->get_results($query);
366
- $query = "select count(*) as count from ".$wpdb->base_prefix."wpns_attack_logs where ip='".$ipaddress."' and input != 'RLE';";
367
  $results = $wpdb->get_results($query);
368
 
369
  if($results[0]->count>$limitAttack)
@@ -381,7 +386,8 @@
381
  }
382
  }
383
  header('HTTP/1.1 403 Forbidden');
384
- include_once("mo-error.php");
 
385
  }
386
  }
387
  }
@@ -401,4 +407,4 @@
401
 
402
 
403
 
404
- ?>
54
  else
55
  {
56
  header('HTTP/1.1 403 Forbidden');
57
+ include_once("mo-block.html");
58
+ exit;
59
  }
60
  }
61
  $dir_name = dirname(__FILE__);
117
  $current_time = time();
118
  if($results[0]->time < $current_time-60)
119
  {
120
+ $query = "insert into ".$wpdb->base_prefix."wpns_attack_logs values('".$ipaddress."','Rate Limit',".time().",'".MoWpnsConstants::RATE_LIMIT_EXCEEDED."');";
121
  $results = $wpdb->get_results($query);
122
  }
123
  header('HTTP/1.1 403 Forbidden');
124
+ include_once("mo-error.html");
125
+ exit;
126
  }
127
  else
128
  {
131
  $current_time = time();
132
  if($results[0]->time < $current_time-60)
133
  {
134
+ $query = "insert into ".$wpdb->base_prefix."wpns_attack_logs values('".$ipaddress."','Rate Limit',".time().",'".MoWpnsConstants::RATE_LIMIT_EXCEEDED."');";
135
  $results = $wpdb->get_results($query);
136
  }
137
  $query = 'select * from '.$wpdb->base_prefix.'mo2f_network_whitelisted_ips where ip_address="'.$ipaddress.'";';
146
  $results =$wpdb->get_results($query);
147
  }
148
  header('HTTP/1.1 403 Forbidden');
149
+ include_once("mo-error.html");
150
+ exit;
151
  }
152
  }
153
  }
229
  $value = htmlspecialchars($value);
230
  $query = 'insert into '.$wpdb->base_prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
231
  $results = $wpdb->get_results($query);
232
+ $query = "select count(*) as count from ".$wpdb->base_prefix."wpns_attack_logs where ip='".$ipaddress."' and input != '".MoWpnsConstants::RATE_LIMIT_EXCEEDED."';";
233
  $results = $wpdb->get_results($query);
234
  if($results[0]->count>$limitAttack)
235
  {
246
  }
247
  }
248
  header('HTTP/1.1 403 Forbidden');
249
+ include_once("mo-error.html");
250
+ exit;
251
  }
252
 
253
  }
298
  $value = htmlspecialchars($value);
299
  $query = 'insert into '.$wpdb->base_prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
300
  $results = $wpdb->get_results($query);
301
+ $query = "select count(*) as count from ".$wpdb->base_prefix."wpns_attack_logs where ip='".$ipaddress."' and input != '".MoWpnsConstants::RATE_LIMIT_EXCEEDED."';";
302
  $results = $wpdb->get_results($query);
303
 
304
  if($results[0]->count>$limitAttack)
316
  }
317
  }
318
  header('HTTP/1.1 403 Forbidden');
319
+ include_once("mo-error.html");
320
+ exit;
321
  }
322
  }
323
  }
368
  $value = htmlspecialchars($value);
369
  $query = 'insert into '.$wpdb->base_prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
370
  $results = $wpdb->get_results($query);
371
+ $query = "select count(*) as count from ".$wpdb->base_prefix."wpns_attack_logs where ip='".$ipaddress."' and input != '".MoWpnsConstants::RATE_LIMIT_EXCEEDED."';";
372
  $results = $wpdb->get_results($query);
373
 
374
  if($results[0]->count>$limitAttack)
386
  }
387
  }
388
  header('HTTP/1.1 403 Forbidden');
389
+ include_once("mo-error.html");
390
+ exit;
391
  }
392
  }
393
  }
407
 
408
 
409
 
410
+ ?>
handler/mo-waf.php CHANGED
@@ -131,13 +131,15 @@
131
  else if(!is_null($row['ip_address']))
132
  {
133
  header('HTTP/1.1 403 Forbidden');
134
- include_once("mo-block.php");
 
135
  }
136
  }
137
  else if(!is_null($row['ip_address']))
138
  {
139
  header('HTTP/1.1 403 Forbidden');
140
- include_once("mo-block.php");
 
141
 
142
  }
143
 
@@ -260,11 +262,12 @@
260
  $current_time = time();
261
  if($current_time>$results['time']+60)
262
  {
263
- $query = "insert into ".$prefix."wpns_attack_logs values('".$ipaddress."','Rate Limit',".time().",'RLE');";
264
  $results = mysqli_query($dbcon,$query);
265
  }
266
  header('HTTP/1.1 403 Forbidden');
267
- include_once("mo-error.php");
 
268
  }
269
  else
270
  {
@@ -274,7 +277,7 @@
274
  $current_time = time();
275
  if($current_time>$results['time']+60)
276
  {
277
- $query = "insert into ".$prefix."wpns_attack_logs values('".$ipaddress."','Rate Limit',".time().",'RLE');";
278
  $results = mysqli_query($dbcon,$query);
279
  }
280
  $query = 'select * from '.$prefix.'mo2f_network_whitelisted_ips where ip_address="'.$ipaddress.'";';
@@ -292,7 +295,8 @@
292
  $results = mysqli_query($dbcon,$query);
293
  }
294
  header('HTTP/1.1 403 Forbidden');
295
- include_once("mo-error.php");
 
296
  }
297
  }
298
  }
@@ -387,7 +391,7 @@
387
  $value = htmlspecialchars($value);
388
  $query = 'insert into '.$prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
389
  $results = mysqli_query($dbcon,$query);
390
- $query = "select count(*) from ".$prefix."wpns_attack_logs where ip='".$ipaddress."' and input != 'RLE';";
391
  $results = mysqli_query($dbcon,$query);
392
  $rows = mysqli_fetch_array($results);
393
  if($rows['count(*)']>$limitAttack)
@@ -411,7 +415,8 @@
411
 
412
 
413
  header('HTTP/1.1 403 Forbidden');
414
- include_once("mo-error.php");
 
415
  }
416
 
417
  }}
@@ -460,7 +465,7 @@
460
  $value = htmlspecialchars($value);
461
  $query = 'insert into '.$prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
462
  $results = mysqli_query($dbcon,$query);
463
- $query = "select count(*) from ".$prefix."wpns_attack_logs where ip='".$ipaddress."' and input != 'RLE';";
464
  $results = mysqli_query($dbcon,$query);
465
  $rows = mysqli_fetch_array($results);
466
  if($rows['count(*)']>$limitAttack)
@@ -484,7 +489,8 @@
484
 
485
 
486
  header('HTTP/1.1 403 Forbidden');
487
- include_once("mo-error.php");
 
488
  }
489
  }}
490
  }
@@ -533,7 +539,7 @@
533
  $value = htmlspecialchars($value);
534
  $query = 'insert into '.$prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
535
  $results = mysqli_query($dbcon,$query);
536
- $query = "select count(*) from ".$prefix."wpns_attack_logs where ip='".$ipaddress."' and input != 'RLE';";
537
  $results = mysqli_query($dbcon,$query);
538
  $rows = mysqli_fetch_array($results);
539
  if($rows['count(*)']>$limitAttack)
@@ -557,7 +563,8 @@
557
 
558
 
559
  header('HTTP/1.1 403 Forbidden');
560
- include_once("mo-error.php");
 
561
  }
562
  }
563
  }
@@ -576,4 +583,4 @@
576
  }
577
 
578
  $dbcon->close();
579
- ?>
131
  else if(!is_null($row['ip_address']))
132
  {
133
  header('HTTP/1.1 403 Forbidden');
134
+ include_once("mo-block.html");
135
+ exit;
136
  }
137
  }
138
  else if(!is_null($row['ip_address']))
139
  {
140
  header('HTTP/1.1 403 Forbidden');
141
+ include_once("mo-block.html");
142
+ exit;
143
 
144
  }
145
 
262
  $current_time = time();
263
  if($current_time>$results['time']+60)
264
  {
265
+ $query = "insert into ".$prefix."wpns_attack_logs values('".$ipaddress."','Rate Limit',".time().",'".MoWpnsConstants::RATE_LIMIT_EXCEEDED."');";
266
  $results = mysqli_query($dbcon,$query);
267
  }
268
  header('HTTP/1.1 403 Forbidden');
269
+ include_once("mo-error.html");
270
+ exit;
271
  }
272
  else
273
  {
277
  $current_time = time();
278
  if($current_time>$results['time']+60)
279
  {
280
+ $query = "insert into ".$prefix."wpns_attack_logs values('".$ipaddress."','Rate Limit',".time().",'".MoWpnsConstants::RATE_LIMIT_EXCEEDED."');";
281
  $results = mysqli_query($dbcon,$query);
282
  }
283
  $query = 'select * from '.$prefix.'mo2f_network_whitelisted_ips where ip_address="'.$ipaddress.'";';
295
  $results = mysqli_query($dbcon,$query);
296
  }
297
  header('HTTP/1.1 403 Forbidden');
298
+ include_once("mo-error.html");
299
+ exit;
300
  }
301
  }
302
  }
391
  $value = htmlspecialchars($value);
392
  $query = 'insert into '.$prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
393
  $results = mysqli_query($dbcon,$query);
394
+ $query = "select count(*) from ".$prefix."wpns_attack_logs where ip='".$ipaddress."' and input != '".MoWpnsConstants::RATE_LIMIT_EXCEEDED."';";
395
  $results = mysqli_query($dbcon,$query);
396
  $rows = mysqli_fetch_array($results);
397
  if($rows['count(*)']>$limitAttack)
415
 
416
 
417
  header('HTTP/1.1 403 Forbidden');
418
+ include_once("mo-error.html");
419
+ exit;
420
  }
421
 
422
  }}
465
  $value = htmlspecialchars($value);
466
  $query = 'insert into '.$prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
467
  $results = mysqli_query($dbcon,$query);
468
+ $query = "select count(*) from ".$prefix."wpns_attack_logs where ip='".$ipaddress."' and input != '".MoWpnsConstants::RATE_LIMIT_EXCEEDED."';";
469
  $results = mysqli_query($dbcon,$query);
470
  $rows = mysqli_fetch_array($results);
471
  if($rows['count(*)']>$limitAttack)
489
 
490
 
491
  header('HTTP/1.1 403 Forbidden');
492
+ include_once("mo-error.html");
493
+ exit;
494
  }
495
  }}
496
  }
539
  $value = htmlspecialchars($value);
540
  $query = 'insert into '.$prefix.'wpns_attack_logs values ("'.$ipaddress.'","'.$value1.'",'.time().',"'.$value.'");';
541
  $results = mysqli_query($dbcon,$query);
542
+ $query = "select count(*) from ".$prefix."wpns_attack_logs where ip='".$ipaddress."' and input != '".MoWpnsConstants::RATE_LIMIT_EXCEEDED."';";
543
  $results = mysqli_query($dbcon,$query);
544
  $rows = mysqli_fetch_array($results);
545
  if($rows['count(*)']>$limitAttack)
563
 
564
 
565
  header('HTTP/1.1 403 Forbidden');
566
+ include_once("mo-error.html");
567
+ exit;
568
  }
569
  }
570
  }
583
  }
584
 
585
  $dbcon->close();
586
+ ?>
handler/recaptcha.php CHANGED
@@ -16,7 +16,7 @@
16
  //Function to handle Testing reCaptcha
17
  function handle_recaptcha()
18
  {
19
- global $moWpnsUtility,$dirName;
20
  if (current_user_can( 'manage_options' ))
21
  {
22
  if(isset($_REQUEST['option']) && $_REQUEST['option']=='testrecaptchaconfig')
@@ -42,9 +42,8 @@
42
 
43
  function custom_login_fields()
44
  {
45
- if(get_option('mo_wpns_activate_recaptcha_for_login'))
46
  {
47
-
48
  echo "<script src='".MoWpnsConstants::RECAPTCHA_URL."'></script>";
49
  echo '<div class="g-recaptcha" data-sitekey="'.get_option("mo_wpns_recaptcha_site_key").'"></div>';
50
  echo '<style>#login{ width:349px;padding:2% 0 0; }.g-recaptcha{margin-bottom:5%;}#loginform{padding-bottom:20px;}</style>';
16
  //Function to handle Testing reCaptcha
17
  function handle_recaptcha()
18
  {
19
+ global $moWpnsUtility,$mo2f_dirName;
20
  if (current_user_can( 'manage_options' ))
21
  {
22
  if(isset($_REQUEST['option']) && $_REQUEST['option']=='testrecaptchaconfig')
42
 
43
  function custom_login_fields()
44
  {
45
+ if(get_option('mo_wpns_activate_recaptcha_for_login') && get_option('mo2f_login_option'))
46
  {
 
47
  echo "<script src='".MoWpnsConstants::RECAPTCHA_URL."'></script>";
48
  echo '<div class="g-recaptcha" data-sitekey="'.get_option("mo_wpns_recaptcha_site_key").'"></div>';
49
  echo '<style>#login{ width:349px;padding:2% 0 0; }.g-recaptcha{margin-bottom:5%;}#loginform{padding-bottom:20px;}</style>';
handler/registration.php CHANGED
@@ -10,16 +10,27 @@
10
  function mo_wpns_registration_validations( $errors, $sanitized_user_login, $user_email )
11
  {
12
  global $moWpnsUtility;
13
-
14
  if(get_option('mo_wpns_activate_recaptcha_for_registration'))
15
  $recaptchaError = $moWpnsUtility->verify_recaptcha($_POST['g-recaptcha-response']);
16
-
17
  if($moWpnsUtility->check_if_valid_email($user_email) && empty($recaptchaError->errors))
18
  $errors->add( 'blocked_email_error', __( '<strong>ERROR</strong>: Your email address is not allowed to register. Please select different email address.') );
19
  else if(!empty($recaptchaError->errors))
20
  $errors = $recaptchaError;
21
 
22
- return $errors;
 
 
 
 
 
 
 
 
 
 
 
23
  }
24
 
25
  }
10
  function mo_wpns_registration_validations( $errors, $sanitized_user_login, $user_email )
11
  {
12
  global $moWpnsUtility;
13
+
14
  if(get_option('mo_wpns_activate_recaptcha_for_registration'))
15
  $recaptchaError = $moWpnsUtility->verify_recaptcha($_POST['g-recaptcha-response']);
16
+ if(get_site_option('mo_wpns_enable_fake_domain_blocking')){
17
  if($moWpnsUtility->check_if_valid_email($user_email) && empty($recaptchaError->errors))
18
  $errors->add( 'blocked_email_error', __( '<strong>ERROR</strong>: Your email address is not allowed to register. Please select different email address.') );
19
  else if(!empty($recaptchaError->errors))
20
  $errors = $recaptchaError;
21
 
22
+ }
23
+ else{
24
+ $count= get_site_option('number_of_fake_reg');
25
+ if($moWpnsUtility->check_if_valid_email($user_email) && empty($recaptchaError->errors))
26
+ {
27
+ $count = $count + 1;
28
+ update_site_option('number_of_fake_reg' ,$count );
29
+ }
30
+ }
31
+ return $errors;
32
+
33
+
34
  }
35
 
36
  }
handler/security_features DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
- class
3
- {
4
-
5
- }
6
- ?>
 
 
 
 
 
 
handler/signature/APLFI.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
 
3
- $regex['LFI'][1] = array( "#(?i)(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\/))(?:%(?:(?:f(?:(?:c%80|8)%8)?0%8|e)0%80%ae|2(?:(?:5(?:c0%25a|2))?e|%45)|u(?:(?:002|ff0)e|2024)|%32(?:%(?:%6|4)5|E)|c0(?:%[256aef]e|\.))|\.(?:%0[01]|\?)?|\?\.?|0x2e){2}(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\/))#" , "# (?:^|[\\/])\.\.(?:[\\/]|$)#","$(?:.(?:(?:(?:(?:mini)?kub|vmwar)e|d(?:ocker|bus)|cups)/|a(?:ws/c(?:redentials|onfig)|(?:nydesk|tom)/)|g(?:(?:nonme|sutil|em)/|itlab-ci.yml)|t(?:hunderbird/|ravis.yml)|j(?:shintrc|ava/)|n(?:[pv]m/|etrc)|bo(?:werrc|to)|eslintrc|idea)|# (?:New (?:Top Level dotf|Per-Project F)iles|common, old network config file|WS FTP|OSX)|/.(?:ws_ftp.ini|DS_Store|env)|database.yml|Dockerfile|bower.json|nbproject/)$","#(?:etc/(?:s(?:e(?:curity/(?:(?:(?:namespac|tim)e|sepermit|access).conf|l(?:imits(?:.conf)?|astlog)|(?:failedlogi|enviro)n|pa(?:m_env.conf|sswd)|group(?:.conf)?|opasswd|user)|nsors3?.conf)|ys(?:c(?:tl(?:.d/(?:10-(?:(?:network|process)-security|console-messages)|wine.sysctl))?.conf|onfig/network-scripts/ifcfg-eth0)|log.conf)|quirrelmail/(?:(?:config(?:_(?:default|local)|/config)?|sqspell_config|filters_setup|index).php|(?:default_pre|apache.con)f)|amba/(?:s(?:mb(?:.conf(?:.user)?|passwd|users)|amba.conf)|private/smbpasswd|dhcp.conf|netlogon)|(?:w-cp-server/applications.d/(?:00-sso-cpserver|plesk)|tunnel/stunnel).conf|u(?:bversion/config|se-release|doers)|s(?:o/sso_config.ini|h/sshd_config)|m(?:b(?:passwd|.conf)|i.conf)|lackware-release|hadow[-~]?)|a(?:p(?:ache(?:2(?:/(?:(?:mods-(?:available/(?:m(?:em_cach|im)e|s(?:etenvif|sl)|d(?:eflate|ir)|autoindex|proxy)|enabled/(?:(?:statu|alia)s|d(?:eflate|ir)|negotiation|mime|php5))|(?:apache|httpd)2?|default-server|ports).conf|s(?:ites-(?:available/default(?:-ssl)?|enabled/(?:000-)?default)|sl-global.conf)|conf(?:.d/(?:phpmyadmin.conf|security|charset)|/httpd.conf)|vhosts.d/(?:00_default_vhost.conf|default_vhost.include)|envvars)|2(?:/conf)?/httpd.conf)|/(?:a(?:ccess|pache)|(?:conf/)?httpd|default-server).conf)|t/apt.conf)|(?:vahi/avahi-daemon|dduser).conf|lias)|p(?:hp(?:(?:(?:(?:4(?:/(?:apache2?|cgi)|.4/fcgi)|5/(?:apache2?|cgi))/|/(?:(?:apache2?|cgi)/|(?:php4/)?))php)?.ini|myadmin/config.inc.php)|u(?:re(?:-ftpd(?:/pure(?:-ftpd.(?:conf|pdb)|ftpd.pdb)|.conf)|ftpd.p(?:asswd|db))|lse/client.conf)|ro(?:f(?:tp(?:d/modules)?.conf|ile)|tpd/proftpd.conf)|a(?:ssw(?:ord.master|d[-~]?)|m.(?:d/proftpd|conf))|ostgresql/p(?:ostgresql|g_hba).conf)|m(?:o(?:no/(?:(?:2.0/(?:machine|web)|1.0/machine).)?config|d(?:probe.d/vmware-tools.conf|ules)|td)|(?:y(?:sql/(?:conf.d/old_passwords|my))?.c|iredo(?:/miredo)?(?:-server)?.co)nf|uddleftpd(?:/(?:mud(?:dleftpd.(?:passwd|conf)|log(?:d.conf)?)|passwd)|.com)|a(?:n(?:drake-release|path.config)|il/sendmail.conf)|t(?:ools.conf|ab))|h(?:ttp(?:d(?:/(?:conf(?:.d(?:/(?:squirrelmail|php).conf)?|/(?:apache2?|httpd).conf)?|(?:extra/httpd-ssl|apache2?|mod_php|httpd).conf|logs/(?:access.)log|php.ini)|.conf)|(?:/conf)?/httpd.conf)|ost(?:s(?:.(?:allow|deny))?|.conf|name)|dparm.conf)|c(?:ups/(?:(?:p(?:rinter|dftop)s|acroread).conf|cupsd.conf(?:.default)?)|(?:lamav/(?:freshclam|clamd)|vs-(?:pserver|cron)).conf|a(?:-certificates.conf(?:.dpkg-old)?|sper.conf)|h(?:krootkit.conf|rootusers)|r(?:ypt|on)tab)|w(?:icd/(?:(?:wire(?:less|d)|manager)-settings.conf|dhclient.conf.template.default)|u-ftpd/ftp(?:acces|host|user)s|ebmin/miniserv.(?:users|conf))|v(?:mware-tools/(?:(?:vmware-tools-libraries|tpvmlp).conf|config)|sftpd(?:.c(?:hroot_list|onf)|/vsftpd.conf)|hcs2/proftpd/proftpd.conf)|l(?:og(?:rotate.(?:d/(?:vsftpd.log|proftpd|ftp)|conf)|in.defs)|(?:ighttpd/lighthttpd|d(?:ap/ldap|.so)|trace).conf)|r(?:e(?:solv(?:conf/update-libc.d/sendmail|.conf)|d(?:is(?:-sentinel)?.conf|hat-release))|c.(?:d/rc.httpd|conf))|d(?:e(?:b(?:ian_version|conf.conf)|fault/grub|luser.conf)|(?:hcp(?:3/dhc(?:lient|pd)|/dhclient)|ns2tcpd).conf)|f(?:tp(?:(?:host|user)s|chroot)|(?:oremost|use).conf|edora-release|irewall.rules|stab)|b(?:luetooth/(?:network|rfcomm|input|main).conf|ash(?:_completion.d/debconf|.bashrc))|x11/xorg.conf(?:.(?:beforevmwaretoolsinstall|orig)|-v(?:mware|esa))?|i(?:n(?:it(?:tab|.d|/)|etd.conf)|pfw.(?:rules|conf)|ssue(?:.net)?)|t(?:i(?:nyproxy/tinyproxy.conf|mezone)|(?:or/tor-t)?socks.conf)|o(?:s(?:xhttpd/osxhttpd.conf|-release)|penldap/ldap.conf)|u(?:pdatedb.conf(?:.beforevmwaretoolsinstall)?|tmp)|n(?:e(?:wsyslog.conf|twork[/s])|ginx/nginx.conf)|e(?:(?:sound/esd|2fsck|tter).conf|xports)|k(?:ernel-(?:im|pk)g.conf|bd/config)|group-?)|usr(?:/(?:l(?:ocal/(?:p(?:hp(?:4/(?:apache(?:2.conf(?:.php)?|.conf(?:.php)?)|httpd.conf(?:.php)?|lib/php.ini)|5/(?:apache(?:2.conf(?:.php)?|.conf(?:.php)?)|httpd.conf(?:.php)?|lib/php.ini)|/(?:apache(?:2.conf(?:.php)?|.conf(?:.php)?)|httpd.conf(?:.php)?|lib/php.ini))|sa/admin/(?:htdocs/domains/databases/phpmyadmin/libraries/config.default.php|conf/(?:site_isolation_settings|php).ini|logs/(?:httpsd_access_|panel.)log)|gsql/(?:data/p(?:ostgresql.(?:conf|log)|g_(?:hba.conf|log)|asswd)|bin/pg_passwd)|ureftpd/(?:etc/pure(?:-ftpd.conf|ftpd.pdb)|sbin/pure-config.pl))|ap(?:ache(?:2(?:/(?:(?:conf/(?:(?:extra/httpd-)?ssl|vhosts(?:-custom)?|apache2?|modsec|httpd)|apache2?|httpd).conf|logs/(?:a(?:ccess.|udit_))?log)|2(?:/conf)?/httpd.conf)|/(?:conf/(?:(?:a(?:pache2?|ccess)|vhosts(?:-custom)?|modsec).conf|httpd.conf(?:.default)?|php.ini)|logs/(?:a(?:ccess.|udit_))?log|(?:apache2?|httpd).conf)|1.3/conf/httpd.conf)|ps/apache(?:2?2)?/conf/httpd.conf)|jakarta/(?:tomcat/(?:conf/(?:(?:logging|workers).properties|(?:context|server).xml|jakarta.conf)|logs/(?:catalina.(?:err|out)|mod_jk.log))|dist/tomcat/(?:conf/(?:(?:logging|workers).properties|(?:context|server).xml|jakarta.conf)|logs/mod_jk.log))|etc/(?:(?:(?:apache(?:2(?:/(?:(?:conf/)?httpd|vhosts)|2(?:/conf)?/httpd)|/(?:(?:conf/)?httpd|vhosts))|nginx/nginx|smb).|httpd/(?:conf/httpd.)?)conf|p(?:ure(?:-ftpd.conf|ftpd.pdb)|hp.ini)|webmin/miniserv.(?:users|conf)|lighttpd.conf(?:.new)?)|l(?:i(?:ghttpd/(?:log/(?:lighttpd.error|access).log|conf/lighttpd.conf)|b/php.ini)|sws/(?:conf/httpd_conf.xml|logs/error.log)|ogs/(?:access|samba).log)|mysql/data/mysql(?:-(?:bin.(?:index|log)|slow.log)|.(?:err|log)|derror.log)|s(?:amba/lib/(?:smb.conf|log).user|quirrelmail/www/readme|b/config)|cpanel/logs/(?:l(?:icense|ogin)|(?:acces|stat)s|error)_log|ze(?:us/web/(?:global.cfg|log/errors)|nd/etc/php.ini)|(?:httpd/conf/httpd|nginx/conf/nginx).conf)|ib/(?:security/mkuser.default|(?:php/)?php.ini|cron/log))|s(?:hare/(?:tomcat(?:6/(?:conf/(?:(?:logging|workers).properties|(?:context|server).xml)|logs/catalina.(?:err|out))|/logs/catalina.(?:err|out))|squirrelmail/(?:plugins/squirrel_logger/setup|config/config).php|logs/catalina.(?:err|out)|adduser/adduser.conf)|bin/(?:mud(?:passw|log)d|pure-config.pl)|pool/(?:mqueue/sys|lp/)log)|p(?:orts/(?:contrib/pure-ftpd/pure(?:ftpd.p(?:asswd|db)|-ftpd.conf)|ftp/pure-ftpd/pure(?:ftpd.p(?:asswd|db)|-ftpd.conf)|net/pure-ftpd/pure(?:ftpd.p(?:asswd|db)|-ftpd.conf))|kg(?:src/net/pureftpd/pure(?:ftpd.p(?:asswd|db)|-ftpd.conf)|/etc/httpd/httpd(?:-(?:default|vhosts))?.conf))|home/user/(?:var/log/(?:lighttpd.error|apache).log|lighttpd/lighttpd.conf)|internet/pgsql/data/p(?:ostmaster.log|g_hba.conf)|(?:apache2?/conf/ht|etc/pure-f)tpd.conf)|\/local\/(?:[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|mysql\/data\/\{host\}.err))|v(?:ar(?:/(?:l(?:o(?:g(?:/(?:p(?:(?:o(?:stgres(?:ql(?:/(?:postgres(?:ql(?:-(?:8.[134]|9.[01])-main)?)?|main))?|/p(?:g_backup|ostgres)).|p)|(?:ure(?:-ftpd/pure-)?ftpd|m-powersave).|gsql(?:(?:/pgsql|8).|_))log|roftpd(?:.(?:access_|xfer)log|/xferlog.legacy)?)|(?:(?:v(?:mware/hostd(?:-1)?|sftpd)|cron/var/log/postgres|webmin/miniserv|boot).|a(?:pache(?:2/(?:(?:access|error).)|/(?:access.))|ccess.|uth.?)|e(?:xim[/_](?:reject|panic|main)|rror.)|httpd/(?:access.)|x(?:org.0.|fer))log|m(?:ysql(?:/(?:mysql(?:-(?:bin.(?:index|log)|slow.log)|.log)|data/mysql-bin.index)|.(?:err|log)|-bin.index|derror.log)|ail(?:.(?:info|warn|err|log)|log)|uddleftpd(?:.conf)?|essages(?:.1)?)|n(?:ews(?:/(?:news.(?:notice|crit|all|err)|suck.(?:notice|err))|.all)|ginx(?:.(?:access|error)_|/(?:access.))log)|s(?:(?:(?:quirrelmail|so/sso).|w-cp-server/error_)log|amba(?:/log.[ns]mbd|.log[12]?)|yslog(?:.1)?)|l(?:ighttpd(?:/(?:(?:access|error)(?:.www)?.log)?|.(?:access|error).log)|og.smb)|da(?:ta/mysql-bin.index|emon.log(?:.1)?)|ftp(?:-proxy(?:/ftp-proxy.log)?|log)|ipfw(?:.(?:today|log)|/ipfw.log)?|u(?:ser.log(?:.1)?|fw.log)|tomcat6/catalina.out|kern.log(?:.1)?)|s/access.log)|cal/www/conf/php.ini)|i(?:b/(?:(?:pgsql/data/postgresql.co|mysql/my.c)nf|squirrelmail/prefs/squirrelmail.log)|ghttpd.log)|p/logs/(?:lp(?:sched|net)|requests))|a(?:dm/(?:l(?:og(?:/(?:asppp.|xfer)|in)log|astlog/username|p/lpd-errs)|(?:ras/(?:boot|err)|s(?:ys|u)|vold.)log|cr(?:ash/(?:vmcore|unix)|on/log)|ac(?:ct/sum/loginlog|ulogs?)|(?:message|x0msg)s|[pq]acct|utmpx?|wtmpx?|dtmp)|pache/conf/httpd.conf)|www/(?:(?:html/squirrelmail(?:-1.2.9)?|squirrelmail)/config/config.php|(?:conf/httpd.)?conf|logs/(?:access.)log|.lighttpdpassword)|postgresql/(?:db/postgresql.conf|log/postgresql.log)|c(?:panel/(?:tomcat.options|cpanel.config)|ron/log)|m(?:ysql(?:-bin.index|.log)|ail/www-data)|data/mysql-bin.index|nm2/postgresql.conf|saf/(?:port/|_)log)|\/log\/lighttpd\/\{domain\}\/(?:access|error).log)|olumes/(?:macintosh_hd1/(?:usr/local/php(?:/(?:httpd.conf.php|lib/php.ini)|[45]/httpd.conf.php)|opt/(?:apache2?|httpd)/conf/httpd.conf)|webbackup/(?:private/etc/httpd/httpd.conf(?:.default)?|opt/apache2/conf/httpd.conf)))|p(?:r(?:o(?:gram files(?:/(?:apache (?:group/apache(?:/(?:(?:conf/(?:apache2?|httpd)|apache2?).conf|logs/(?:access|error).log)|2/conf/(?:apache2?|httpd).conf)|software foundation/apache2.2/(?:logs/(?:access|error).log|conf/httpd.conf))|mysql/(?:my(?:sql server 5.0/(?:data/mysql(?:-bin.(?:index|log)|.(?:err|log))|my.(?:cnf|ini))|.(?:cnf|ini))|data/mysql(?:-bin.(?:index|log)|.(?:err|log)))|(?:postgresql/(?:8.[34]|9.[01])/data/p(?:g_(?:ident|hba)|ostgresql)|xampp/apache/conf/(?:apache2?|httpd)|vidalia bundle/polipo/polipo).conf)|\/(?:[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|mysql(?:\/mysql server 5.0)?\/data\/\{host\}.err))|c/(?:self/(?:fd/(?:[023456789]|1[012345]?)|stat(?:us)?|cmdline|environ|mounts)|(?:cpu|mem)info|net/(?:tc|ud)p|devices|version))|ivate(?:\/tmp\/[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|/etc/(?:httpd/(?:httpd.conf(?:.default)?|apache2?.conf)|squirrelmail/config/config.php)))|a(?:ckage(?:-lock)?.json|rameters.yml)|ostgresql/log/pgadmin.log|hp[45]?/php.ini)|w(?:in(?:dows/(?:s(?:ystem32/(?:logfiles/(?:firewall/pfirewall.log(?:.old)?|w3svc[123]?/inetsvn1.log|smtpsvc[12345]?|msftpsvc[12]?)|drivers/etc/(?:(?:network|service|host)s|lmhosts.sam|protocol)|macromed/flash/(?:flash)?install.log)|etup(?:a(?:ct|pi)|err).log)|(?:(?:debug/net|repair/|com)setup|w(?:indowsupdate|msetup)|updspapi).log|(?:odbc|php).ini)|nt/(?:system32/logfiles/(?:firewall/pfirewall.log(?:.old)?|w3svc[123]?/inetsvn1.log|smtpsvc[12345]?|msftpsvc[12]?)|repair/sam._|php.ini))|amp/(?:bin/(?:apache/apache2.2.2(?:2/(?:(?:conf/(?:wampserver|httpd)|wampserver).conf|logs/(?:access|error).log)|1/(?:(?:conf/httpd|wampserver).conf|logs/(?:access|error).log))|mysql/mysql5.5.(?:16/(?:data/mysql-bin.index|wampserver.conf|my.ini)|24/(?:data/mysql-bin.index|wampserver.conf|my.ini))|php/php5.(?:3.8|4.3)/php.ini)|logs/(?:a(?:pache_error|ccess)|(?:slow|gen)query|mysql).log)|ww/(?:logs/(?:freebsddiary-(?:access_|error.)|proftpd.system.)log|(?:apache/)?conf/httpd.conf)|p-config.(?:t(?:e?mp|xt)|bak|old|php)|eb(?:pack.config.js|/conf/php.ini))|\.(?:s(?:sh/(?:id(?:_(?:dsa(?:.pub)?|rsa(?:.pub)?)|entity(?:.pub)?)|(?:authorized_key|known_host)s|config)|ubversion/(?:servers|config|auth)|(?:qlite|h)_history)|c(?:onfig/odesk/odesk team.conf|ache/notify-osd.log|shrc)|l(?:(?:ocal/share/mc|ftp)/|(?:ldb-)?history|esshst)|h(?:t(?:access|digest|passwd)|plip/hplip.conf)|p(?:(?:ython|sql|hp)_history|rofile|earrc|ki/)|bash(?:_(?:history|profile|config|logout)|rc)|(?:(?:(?:rediscli|ksh)_|R)histor|xauthorit)y|vi(?:dalia/vidalia.conf|m(?:info|rc))|n(?:(?:ode_repl|ano)_history|sr)|z(?:sh(?:_history|rc)|history)|tc(?:onn/tconn.conf|shrc)|my(?:sql_history|.cnf)|g(?:itconfig|nupg/)|aptitude/config|drush/)|o(?:pt(?:/(?:(?:apache(?:2(?:/(?:conf/(?:apache2?|httpd)|apache2?)|2/conf/httpd)|/(?:conf/(?:apache2?|httpd)|apache2?))|httpd/(?:conf/)?apache2?).conf|l(?:sws/(?:logs/(?:access|error).log|conf/httpd_conf.xml)|ampp/(?:logs/(?:access.)log|etc/httpd.conf))|xampp/(?:logs/(?:access.)log|etc/php.ini)|tomcat/logs/catalina.(?:err|out))|\/[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log))|rmconfig.json)|xampp(?:/(?:apache/(?:logs/(?:access|error).log|conf/httpd.conf|bin/php.ini)|m(?:ysql/data/mysql(?:-bin.index|.err)|ercurymail/mercury.ini)|htdocs/(?:a(?:dmin.php|ca.txt)|leer.txt)|php(?:myadmin/config.inc.php|/php.ini)|filezillaftp/filezilla server.xml|sendmail/sendmail.(?:ini|log)|webalizer/webalizer.conf)|\/mysql\/data\/\{host\}.err)|s(?:ystem(?:32/(?:inetsrv/config/(?:a(?:pplicationhost|dministration)|redirection).config|config/(?:s(?:(?:yste|a)m|oftware)|default))|/library/webobjects/adaptors/apache2.2/apache.conf)|(?:ites/default/(?:settings(?:.local)?|default.settings)|rv/www/htdos/squirrelmail/config/config).php|e(?:curity|rvices).yml|ftp-config.json)|t(?:mp(?:\/[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|/access.log)|ypo3conf/localconf.php|sconfig.json)|[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|h(?:ome(?:/(?:postgres/data/p(?:g_(?:(?:ident|hba).conf|version)|ostgresql.conf)|user/lighttpd/lighttpd.conf|bin/stable/apache/php.ini)|2/bin/stable/apache/php.ini)|ttp/httpd.conf)|ap(?:ache(?:/(?:logs/(?:access|error).log|conf/httpd.conf|php/php.ini)|2/logs/(?:access|error).log)|p/etc/local.xml)|l(?:ibrary/webserver/documents/(?:default.(?:html?|php)|index.(?:html?|php))|ogs/(?:security(?:_debug)?_)?log)|mysql(?:/(?:data/mysql(?:-bin.(?:index|log)|.(?:err|log))|my.(?:cnf|ini)|bin/my.ini)|\/data\/\{host\}.err)|ro(?:ot/.(?:bash(?:_(?:history|config|logout)|rc)|(?:ksh_histor|xauthorit)y)|uting.yml)|config(?:/(?:database|custom|app).php|_(?:prod|test|dev).yml|.(?:inc.php|yml))|in(?:c(?:ludes/config(?:ure)?|/config).php|etpub/wwwroot/global.asa)|n(?:etserver/bin/stable/apache/php.ini|pm-debug.log)|b(?:oot/grub/(?:grub.cfg|menu.lst)|in/php.ini)|/(?:config(?:uration)?.php|boot.ini|etc/)|LocalSettings.php|gruntfile.js|Web.config|yarn.lock)#" );
4
  $score['LFI'][1] = array( 5 , 5, 5, 5 );
5
  ?>
1
  <?php
2
 
3
+ $regex['LFI'][1] = array( "#(?i)(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\/))(?:%(?:(?:f(?:(?:c%80|8)%8)?0%8|e)0%80%ae|2(?:(?:5(?:c0%25a|2))?e|%45)|u(?:(?:002|ff0)e|2024)|%32(?:%(?:%6|4)5|E)|c0(?:%[256aef]e|\.))|\.(?:%0[01]|\?)?|\?\.?|0x2e){2}(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\/))#" , "# (?:^|[\\/])\.\.(?:[\\/]|$)#","#(?:etc/(?:s(?:e(?:curity/(?:(?:(?:namespac|tim)e|sepermit|access).conf|l(?:imits(?:.conf)?|astlog)|(?:failedlogi|enviro)n|pa(?:m_env.conf|sswd)|group(?:.conf)?|opasswd|user)|nsors3?.conf)|ys(?:c(?:tl(?:.d/(?:10-(?:(?:network|process)-security|console-messages)|wine.sysctl))?.conf|onfig/network-scripts/ifcfg-eth0)|log.conf)|quirrelmail/(?:(?:config(?:_(?:default|local)|/config)?|sqspell_config|filters_setup|index).php|(?:default_pre|apache.con)f)|amba/(?:s(?:mb(?:.conf(?:.user)?|passwd|users)|amba.conf)|private/smbpasswd|dhcp.conf|netlogon)|(?:w-cp-server/applications.d/(?:00-sso-cpserver|plesk)|tunnel/stunnel).conf|u(?:bversion/config|se-release|doers)|s(?:o/sso_config.ini|h/sshd_config)|m(?:b(?:passwd|.conf)|i.conf)|lackware-release|hadow[-~]?)|a(?:p(?:ache(?:2(?:/(?:(?:mods-(?:available/(?:m(?:em_cach|im)e|s(?:etenvif|sl)|d(?:eflate|ir)|autoindex|proxy)|enabled/(?:(?:statu|alia)s|d(?:eflate|ir)|negotiation|mime|php5))|(?:apache|httpd)2?|default-server|ports).conf|s(?:ites-(?:available/default(?:-ssl)?|enabled/(?:000-)?default)|sl-global.conf)|conf(?:.d/(?:phpmyadmin.conf|security|charset)|/httpd.conf)|vhosts.d/(?:00_default_vhost.conf|default_vhost.include)|envvars)|2(?:/conf)?/httpd.conf)|/(?:a(?:ccess|pache)|(?:conf/)?httpd|default-server).conf)|t/apt.conf)|(?:vahi/avahi-daemon|dduser).conf|lias)|p(?:hp(?:(?:(?:(?:4(?:/(?:apache2?|cgi)|.4/fcgi)|5/(?:apache2?|cgi))/|/(?:(?:apache2?|cgi)/|(?:php4/)?))php)?.ini|myadmin/config.inc.php)|u(?:re(?:-ftpd(?:/pure(?:-ftpd.(?:conf|pdb)|ftpd.pdb)|.conf)|ftpd.p(?:asswd|db))|lse/client.conf)|ro(?:f(?:tp(?:d/modules)?.conf|ile)|tpd/proftpd.conf)|a(?:ssw(?:ord.master|d[-~]?)|m.(?:d/proftpd|conf))|ostgresql/p(?:ostgresql|g_hba).conf)|m(?:o(?:no/(?:(?:2.0/(?:machine|web)|1.0/machine).)?config|d(?:probe.d/vmware-tools.conf|ules)|td)|(?:y(?:sql/(?:conf.d/old_passwords|my))?.c|iredo(?:/miredo)?(?:-server)?.co)nf|uddleftpd(?:/(?:mud(?:dleftpd.(?:passwd|conf)|log(?:d.conf)?)|passwd)|.com)|a(?:n(?:drake-release|path.config)|il/sendmail.conf)|t(?:ools.conf|ab))|h(?:ttp(?:d(?:/(?:conf(?:.d(?:/(?:squirrelmail|php).conf)?|/(?:apache2?|httpd).conf)?|(?:extra/httpd-ssl|apache2?|mod_php|httpd).conf|logs/(?:access.)log|php.ini)|.conf)|(?:/conf)?/httpd.conf)|ost(?:s(?:.(?:allow|deny))?|.conf|name)|dparm.conf)|c(?:ups/(?:(?:p(?:rinter|dftop)s|acroread).conf|cupsd.conf(?:.default)?)|(?:lamav/(?:freshclam|clamd)|vs-(?:pserver|cron)).conf|a(?:-certificates.conf(?:.dpkg-old)?|sper.conf)|h(?:krootkit.conf|rootusers)|r(?:ypt|on)tab)|w(?:icd/(?:(?:wire(?:less|d)|manager)-settings.conf|dhclient.conf.template.default)|u-ftpd/ftp(?:acces|host|user)s|ebmin/miniserv.(?:users|conf))|v(?:mware-tools/(?:(?:vmware-tools-libraries|tpvmlp).conf|config)|sftpd(?:.c(?:hroot_list|onf)|/vsftpd.conf)|hcs2/proftpd/proftpd.conf)|l(?:og(?:rotate.(?:d/(?:vsftpd.log|proftpd|ftp)|conf)|in.defs)|(?:ighttpd/lighthttpd|d(?:ap/ldap|.so)|trace).conf)|r(?:e(?:solv(?:conf/update-libc.d/sendmail|.conf)|d(?:is(?:-sentinel)?.conf|hat-release))|c.(?:d/rc.httpd|conf))|d(?:e(?:b(?:ian_version|conf.conf)|fault/grub|luser.conf)|(?:hcp(?:3/dhc(?:lient|pd)|/dhclient)|ns2tcpd).conf)|f(?:tp(?:(?:host|user)s|chroot)|(?:oremost|use).conf|edora-release|irewall.rules|stab)|b(?:luetooth/(?:network|rfcomm|input|main).conf|ash(?:_completion.d/debconf|.bashrc))|x11/xorg.conf(?:.(?:beforevmwaretoolsinstall|orig)|-v(?:mware|esa))?|i(?:n(?:it(?:tab|.d|/)|etd.conf)|pfw.(?:rules|conf)|ssue(?:.net)?)|t(?:i(?:nyproxy/tinyproxy.conf|mezone)|(?:or/tor-t)?socks.conf)|o(?:s(?:xhttpd/osxhttpd.conf|-release)|penldap/ldap.conf)|u(?:pdatedb.conf(?:.beforevmwaretoolsinstall)?|tmp)|n(?:e(?:wsyslog.conf|twork[/s])|ginx/nginx.conf)|e(?:(?:sound/esd|2fsck|tter).conf|xports)|k(?:ernel-(?:im|pk)g.conf|bd/config)|group-?)|usr(?:/(?:l(?:ocal/(?:p(?:hp(?:4/(?:apache(?:2.conf(?:.php)?|.conf(?:.php)?)|httpd.conf(?:.php)?|lib/php.ini)|5/(?:apache(?:2.conf(?:.php)?|.conf(?:.php)?)|httpd.conf(?:.php)?|lib/php.ini)|/(?:apache(?:2.conf(?:.php)?|.conf(?:.php)?)|httpd.conf(?:.php)?|lib/php.ini))|sa/admin/(?:htdocs/domains/databases/phpmyadmin/libraries/config.default.php|conf/(?:site_isolation_settings|php).ini|logs/(?:httpsd_access_|panel.)log)|gsql/(?:data/p(?:ostgresql.(?:conf|log)|g_(?:hba.conf|log)|asswd)|bin/pg_passwd)|ureftpd/(?:etc/pure(?:-ftpd.conf|ftpd.pdb)|sbin/pure-config.pl))|ap(?:ache(?:2(?:/(?:(?:conf/(?:(?:extra/httpd-)?ssl|vhosts(?:-custom)?|apache2?|modsec|httpd)|apache2?|httpd).conf|logs/(?:a(?:ccess.|udit_))?log)|2(?:/conf)?/httpd.conf)|/(?:conf/(?:(?:a(?:pache2?|ccess)|vhosts(?:-custom)?|modsec).conf|httpd.conf(?:.default)?|php.ini)|logs/(?:a(?:ccess.|udit_))?log|(?:apache2?|httpd).conf)|1.3/conf/httpd.conf)|ps/apache(?:2?2)?/conf/httpd.conf)|jakarta/(?:tomcat/(?:conf/(?:(?:logging|workers).properties|(?:context|server).xml|jakarta.conf)|logs/(?:catalina.(?:err|out)|mod_jk.log))|dist/tomcat/(?:conf/(?:(?:logging|workers).properties|(?:context|server).xml|jakarta.conf)|logs/mod_jk.log))|etc/(?:(?:(?:apache(?:2(?:/(?:(?:conf/)?httpd|vhosts)|2(?:/conf)?/httpd)|/(?:(?:conf/)?httpd|vhosts))|nginx/nginx|smb).|httpd/(?:conf/httpd.)?)conf|p(?:ure(?:-ftpd.conf|ftpd.pdb)|hp.ini)|webmin/miniserv.(?:users|conf)|lighttpd.conf(?:.new)?)|l(?:i(?:ghttpd/(?:log/(?:lighttpd.error|access).log|conf/lighttpd.conf)|b/php.ini)|sws/(?:conf/httpd_conf.xml|logs/error.log)|ogs/(?:access|samba).log)|mysql/data/mysql(?:-(?:bin.(?:index|log)|slow.log)|.(?:err|log)|derror.log)|s(?:amba/lib/(?:smb.conf|log).user|quirrelmail/www/readme|b/config)|cpanel/logs/(?:l(?:icense|ogin)|(?:acces|stat)s|error)_log|ze(?:us/web/(?:global.cfg|log/errors)|nd/etc/php.ini)|(?:httpd/conf/httpd|nginx/conf/nginx).conf)|ib/(?:security/mkuser.default|(?:php/)?php.ini|cron/log))|s(?:hare/(?:tomcat(?:6/(?:conf/(?:(?:logging|workers).properties|(?:context|server).xml)|logs/catalina.(?:err|out))|/logs/catalina.(?:err|out))|squirrelmail/(?:plugins/squirrel_logger/setup|config/config).php|logs/catalina.(?:err|out)|adduser/adduser.conf)|bin/(?:mud(?:passw|log)d|pure-config.pl)|pool/(?:mqueue/sys|lp/)log)|p(?:orts/(?:contrib/pure-ftpd/pure(?:ftpd.p(?:asswd|db)|-ftpd.conf)|ftp/pure-ftpd/pure(?:ftpd.p(?:asswd|db)|-ftpd.conf)|net/pure-ftpd/pure(?:ftpd.p(?:asswd|db)|-ftpd.conf))|kg(?:src/net/pureftpd/pure(?:ftpd.p(?:asswd|db)|-ftpd.conf)|/etc/httpd/httpd(?:-(?:default|vhosts))?.conf))|home/user/(?:var/log/(?:lighttpd.error|apache).log|lighttpd/lighttpd.conf)|internet/pgsql/data/p(?:ostmaster.log|g_hba.conf)|(?:apache2?/conf/ht|etc/pure-f)tpd.conf)|\/local\/(?:[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|mysql\/data\/\{host\}.err))|v(?:ar(?:/(?:l(?:o(?:g(?:/(?:p(?:(?:o(?:stgres(?:ql(?:/(?:postgres(?:ql(?:-(?:8.[134]|9.[01])-main)?)?|main))?|/p(?:g_backup|ostgres)).|p)|(?:ure(?:-ftpd/pure-)?ftpd|m-powersave).|gsql(?:(?:/pgsql|8).|_))log|roftpd(?:.(?:access_|xfer)log|/xferlog.legacy)?)|(?:(?:v(?:mware/hostd(?:-1)?|sftpd)|cron/var/log/postgres|webmin/miniserv|boot).|a(?:pache(?:2/(?:(?:access|error).)|/(?:access.))|ccess.|uth.?)|e(?:xim[/_](?:reject|panic|main)|rror.)|httpd/(?:access.)|x(?:org.0.|fer))log|m(?:ysql(?:/(?:mysql(?:-(?:bin.(?:index|log)|slow.log)|.log)|data/mysql-bin.index)|.(?:err|log)|-bin.index|derror.log)|ail(?:.(?:info|warn|err|log)|log)|uddleftpd(?:.conf)?|essages(?:.1)?)|n(?:ews(?:/(?:news.(?:notice|crit|all|err)|suck.(?:notice|err))|.all)|ginx(?:.(?:access|error)_|/(?:access.))log)|s(?:(?:(?:quirrelmail|so/sso).|w-cp-server/error_)log|amba(?:/log.[ns]mbd|.log[12]?)|yslog(?:.1)?)|l(?:ighttpd(?:/(?:(?:access|error)(?:.www)?.log)?|.(?:access|error).log)|og.smb)|da(?:ta/mysql-bin.index|emon.log(?:.1)?)|ftp(?:-proxy(?:/ftp-proxy.log)?|log)|ipfw(?:.(?:today|log)|/ipfw.log)?|u(?:ser.log(?:.1)?|fw.log)|tomcat6/catalina.out|kern.log(?:.1)?)|s/access.log)|cal/www/conf/php.ini)|i(?:b/(?:(?:pgsql/data/postgresql.co|mysql/my.c)nf|squirrelmail/prefs/squirrelmail.log)|ghttpd.log)|p/logs/(?:lp(?:sched|net)|requests))|a(?:dm/(?:l(?:og(?:/(?:asppp.|xfer)|in)log|astlog/username|p/lpd-errs)|(?:ras/(?:boot|err)|s(?:ys|u)|vold.)log|cr(?:ash/(?:vmcore|unix)|on/log)|ac(?:ct/sum/loginlog|ulogs?)|(?:message|x0msg)s|[pq]acct|utmpx?|wtmpx?|dtmp)|pache/conf/httpd.conf)|www/(?:(?:html/squirrelmail(?:-1.2.9)?|squirrelmail)/config/config.php|(?:conf/httpd.)?conf|logs/(?:access.)log|.lighttpdpassword)|postgresql/(?:db/postgresql.conf|log/postgresql.log)|c(?:panel/(?:tomcat.options|cpanel.config)|ron/log)|m(?:ysql(?:-bin.index|.log)|ail/www-data)|data/mysql-bin.index|nm2/postgresql.conf|saf/(?:port/|_)log)|\/log\/lighttpd\/\{domain\}\/(?:access|error).log)|olumes/(?:macintosh_hd1/(?:usr/local/php(?:/(?:httpd.conf.php|lib/php.ini)|[45]/httpd.conf.php)|opt/(?:apache2?|httpd)/conf/httpd.conf)|webbackup/(?:private/etc/httpd/httpd.conf(?:.default)?|opt/apache2/conf/httpd.conf)))|p(?:r(?:o(?:gram files(?:/(?:apache (?:group/apache(?:/(?:(?:conf/(?:apache2?|httpd)|apache2?).conf|logs/(?:access|error).log)|2/conf/(?:apache2?|httpd).conf)|software foundation/apache2.2/(?:logs/(?:access|error).log|conf/httpd.conf))|mysql/(?:my(?:sql server 5.0/(?:data/mysql(?:-bin.(?:index|log)|.(?:err|log))|my.(?:cnf|ini))|.(?:cnf|ini))|data/mysql(?:-bin.(?:index|log)|.(?:err|log)))|(?:postgresql/(?:8.[34]|9.[01])/data/p(?:g_(?:ident|hba)|ostgresql)|xampp/apache/conf/(?:apache2?|httpd)|vidalia bundle/polipo/polipo).conf)|\/(?:[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|mysql(?:\/mysql server 5.0)?\/data\/\{host\}.err))|c/(?:self/(?:fd/(?:[023456789]|1[012345]?)|stat(?:us)?|cmdline|environ|mounts)|(?:cpu|mem)info|net/(?:tc|ud)p|devices|version))|ivate(?:\/tmp\/[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|/etc/(?:httpd/(?:httpd.conf(?:.default)?|apache2?.conf)|squirrelmail/config/config.php)))|a(?:ckage(?:-lock)?.json|rameters.yml)|ostgresql/log/pgadmin.log|hp[45]?/php.ini)|w(?:in(?:dows/(?:s(?:ystem32/(?:logfiles/(?:firewall/pfirewall.log(?:.old)?|w3svc[123]?/inetsvn1.log|smtpsvc[12345]?|msftpsvc[12]?)|drivers/etc/(?:(?:network|service|host)s|lmhosts.sam|protocol)|macromed/flash/(?:flash)?install.log)|etup(?:a(?:ct|pi)|err).log)|(?:(?:debug/net|repair/|com)setup|w(?:indowsupdate|msetup)|updspapi).log|(?:odbc|php).ini)|nt/(?:system32/logfiles/(?:firewall/pfirewall.log(?:.old)?|w3svc[123]?/inetsvn1.log|smtpsvc[12345]?|msftpsvc[12]?)|repair/sam._|php.ini))|amp/(?:bin/(?:apache/apache2.2.2(?:2/(?:(?:conf/(?:wampserver|httpd)|wampserver).conf|logs/(?:access|error).log)|1/(?:(?:conf/httpd|wampserver).conf|logs/(?:access|error).log))|mysql/mysql5.5.(?:16/(?:data/mysql-bin.index|wampserver.conf|my.ini)|24/(?:data/mysql-bin.index|wampserver.conf|my.ini))|php/php5.(?:3.8|4.3)/php.ini)|logs/(?:a(?:pache_error|ccess)|(?:slow|gen)query|mysql).log)|ww/(?:logs/(?:freebsddiary-(?:access_|error.)|proftpd.system.)log|(?:apache/)?conf/httpd.conf)|p-config.(?:t(?:e?mp|xt)|bak|old|php)|eb(?:pack.config.js|/conf/php.ini))|\.(?:s(?:sh/(?:id(?:_(?:dsa(?:.pub)?|rsa(?:.pub)?)|entity(?:.pub)?)|(?:authorized_key|known_host)s|config)|ubversion/(?:servers|config|auth)|(?:qlite|h)_history)|c(?:onfig/odesk/odesk team.conf|ache/notify-osd.log|shrc)|l(?:(?:ocal/share/mc|ftp)/|(?:ldb-)?history|esshst)|h(?:t(?:access|digest|passwd)|plip/hplip.conf)|p(?:(?:ython|sql|hp)_history|rofile|earrc|ki/)|bash(?:_(?:history|profile|config|logout)|rc)|(?:(?:(?:rediscli|ksh)_|R)histor|xauthorit)y|vi(?:dalia/vidalia.conf|m(?:info|rc))|n(?:(?:ode_repl|ano)_history|sr)|z(?:sh(?:_history|rc)|history)|tc(?:onn/tconn.conf|shrc)|my(?:sql_history|.cnf)|g(?:itconfig|nupg/)|aptitude/config|drush/)|o(?:pt(?:/(?:(?:apache(?:2(?:/(?:conf/(?:apache2?|httpd)|apache2?)|2/conf/httpd)|/(?:conf/(?:apache2?|httpd)|apache2?))|httpd/(?:conf/)?apache2?).conf|l(?:sws/(?:logs/(?:access|error).log|conf/httpd_conf.xml)|ampp/(?:logs/(?:access.)log|etc/httpd.conf))|xampp/(?:logs/(?:access.)log|etc/php.ini)|tomcat/logs/catalina.(?:err|out))|\/[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log))|rmconfig.json)|xampp(?:/(?:apache/(?:logs/(?:access|error).log|conf/httpd.conf|bin/php.ini)|m(?:ysql/data/mysql(?:-bin.index|.err)|ercurymail/mercury.ini)|htdocs/(?:a(?:dmin.php|ca.txt)|leer.txt)|php(?:myadmin/config.inc.php|/php.ini)|filezillaftp/filezilla server.xml|sendmail/sendmail.(?:ini|log)|webalizer/webalizer.conf)|\/mysql\/data\/\{host\}.err)|s(?:ystem(?:32/(?:inetsrv/config/(?:a(?:pplicationhost|dministration)|redirection).config|config/(?:s(?:(?:yste|a)m|oftware)|default))|/library/webobjects/adaptors/apache2.2/apache.conf)|(?:ites/default/(?:settings(?:.local)?|default.settings)|rv/www/htdos/squirrelmail/config/config).php|e(?:curity|rvices).yml|ftp-config.json)|t(?:mp(?:\/[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|/access.log)|ypo3conf/localconf.php|sconfig.json)|[jboss]\/server\/default\/(?:conf\/(?:s(?:tandardj(?:bos|aw)s.xml|erver.log.properties)|j(?:boss-(?:minimal|service).xml|ndi.properties)|log(?:in-config|4j).xml)|deploy\/jboss-logging.xml|log\/(?:server|boot).log)|h(?:ome(?:/(?:postgres/data/p(?:g_(?:(?:ident|hba).conf|version)|ostgresql.conf)|user/lighttpd/lighttpd.conf|bin/stable/apache/php.ini)|2/bin/stable/apache/php.ini)|ttp/httpd.conf)|ap(?:ache(?:/(?:logs/(?:access|error).log|conf/httpd.conf|php/php.ini)|2/logs/(?:access|error).log)|p/etc/local.xml)|l(?:ibrary/webserver/documents/(?:default.(?:html?|php)|index.(?:html?|php))|ogs/(?:security(?:_debug)?_)?log)|mysql(?:/(?:data/mysql(?:-bin.(?:index|log)|.(?:err|log))|my.(?:cnf|ini)|bin/my.ini)|\/data\/\{host\}.err)|ro(?:ot/.(?:bash(?:_(?:history|config|logout)|rc)|(?:ksh_histor|xauthorit)y)|uting.yml)|config(?:/(?:database|custom|app).php|_(?:prod|test|dev).yml|.(?:inc.php|yml))|in(?:c(?:ludes/config(?:ure)?|/config).php|etpub/wwwroot/global.asa)|n(?:etserver/bin/stable/apache/php.ini|pm-debug.log)|b(?:oot/grub/(?:grub.cfg|menu.lst)|in/php.ini)|/(?:config(?:uration)?.php|boot.ini|etc/)|LocalSettings.php|gruntfile.js|Web.config|yarn.lock)#" );
4
  $score['LFI'][1] = array( 5 , 5, 5, 5 );
5
  ?>
handler/{encryption.php → twofa/encryption.php} RENAMED
@@ -30,7 +30,6 @@ class mo2f_GAuth_AESEncryption {
30
  * @return string
31
  */
32
  public static function decrypt_data($data, $key) {
33
-
34
  $c = base64_decode($data);
35
  $ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
36
  $iv = substr($c, 0, $ivlen);
@@ -38,7 +37,7 @@ class mo2f_GAuth_AESEncryption {
38
  $ciphertext_raw = substr($c, $ivlen+$sha2len);
39
  $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
40
  $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
41
-
42
 
43
  return $original_plaintext;
44
  }
30
  * @return string
31
  */
32
  public static function decrypt_data($data, $key) {
 
33
  $c = base64_decode($data);
34
  $ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
35
  $iv = substr($c, 0, $ivlen);
37
  $ciphertext_raw = substr($c, $ivlen+$sha2len);
38
  $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
39
  $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
40
+
41
 
42
  return $original_plaintext;
43
  }
handler/{gaonprem.php → twofa/gaonprem.php} RENAMED
@@ -1,5 +1,5 @@
1
  <?php
2
- include_once dirname( __FILE__ ) . '/encryption.php';
3
  class Google_auth_onpremise{
4
  protected $_codeLength = 6;
5
  function __construct(){
@@ -8,6 +8,7 @@ class Google_auth_onpremise{
8
 
9
  function mo_GAuth_get_details()
10
  {
 
11
  $user=wp_get_current_user();
12
  $user_id=$user->ID;
13
  if(!isset($_SESSION)){
@@ -108,17 +109,16 @@ class Google_auth_onpremise{
108
  }
109
 
110
  if (strlen($code) != 6) {
111
- return $response;
112
  }
113
  for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
114
  $calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
115
  if ($this->timingSafeEquals($calculatedCode, $code)) {
116
  $response['status']='SUCCESS';
117
- return $response;
118
  }
119
  }
120
-
121
- return $response;
122
  }
123
 
124
  function geturl($secret,$issuer,$email){
1
  <?php
2
+ include_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR.'encryption.php';
3
  class Google_auth_onpremise{
4
  protected $_codeLength = 6;
5
  function __construct(){
8
 
9
  function mo_GAuth_get_details()
10
  {
11
+
12
  $user=wp_get_current_user();
13
  $user_id=$user->ID;
14
  if(!isset($_SESSION)){
109
  }
110
 
111
  if (strlen($code) != 6) {
112
+ return json_encode($response);
113
  }
114
  for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
115
  $calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
116
  if ($this->timingSafeEquals($calculatedCode, $code)) {
117
  $response['status']='SUCCESS';
118
+ return json_encode($response);
119
  }
120
  }
121
+ return json_encode($response);
 
122
  }
123
 
124
  function geturl($secret,$issuer,$email){
handler/twofa/setup_twofa.php CHANGED
@@ -1,20 +1,20 @@
1
  <?php
2
-
3
- $setup_dirName = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'setup'.DIRECTORY_SEPARATOR;
4
- $test_dirName = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'test'.DIRECTORY_SEPARATOR;
5
- include $setup_dirName.'setup_google_authenticator.php';
6
- include $setup_dirName.'setup_google_authenticator_onpremise.php';
7
- include $setup_dirName.'setup_authy_authenticator.php';
8
- include $setup_dirName.'setup_kba_questions.php';
9
- include $setup_dirName.'setup_miniorange_authenticator.php';
10
- include $setup_dirName.'setup_otp_over_sms.php';
11
- include $test_dirName.'test_twofa_email_verification.php';
12
- include $test_dirName.'test_twofa_google_authy_authenticator.php';
13
- include $test_dirName.'test_twofa_miniorange_qrcode_authentication.php';
14
- include $test_dirName.'test_twofa_kba_questions.php';
15
- include $test_dirName.'test_twofa_miniorange_push_notification.php';
16
- include $test_dirName.'test_twofa_miniorange_soft_token.php';
17
- include $test_dirName.'test_twofa_otp_over_sms.php';
18
 
19
  function mo2f_decode_2_factor( $selected_2_factor_method, $decode_type ) {
20
 
@@ -83,7 +83,6 @@
83
  "OTP Over SMS and Email",
84
  "Hardware Token"
85
  );
86
-
87
  $two_factor_methods_descriptions = array(
88
  ""=>"<b>All methods in the FREE Plan in addition to the following methods.</b>",
89
  "miniOrange QR Code Authentication" => "Scan the QR code from the account in your miniOrange Authenticator App to login.",
@@ -99,15 +98,44 @@
99
  "Hardware Token" => "Enter the One Time Passcode on your Hardware Token to login."
100
  );
101
 
 
102
  $two_factor_methods_EC = array_slice( $all_two_factor_methods, 0, 8 );
103
  $two_factor_methods_NC = array_slice( $all_two_factor_methods, 0, 5 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  $is_customer_registered = $Mo2fdbQueries->get_user_detail( 'user_registration_with_miniorange', $user->ID ) == 'SUCCESS' ? true : false;
106
-
107
  $can_user_configure_2fa_method = $can_display_admin_features || ( !$can_display_admin_features && $is_customer_registered );
108
  $is_NC = get_option( 'mo2f_is_NC' );
109
  $is_EC = ! $is_NC;
110
-
111
  $form = '';
112
  $form .= '<form name="f" method="post" action="" id="mo2f_save_' . $category . '_auth_methods_form">
113
  <div id="mo2f_' . $category . '_auth_methods" >
@@ -119,6 +147,13 @@
119
  $form .= '<tr>';
120
  for ( $j = 0; $j < count( $auth_methods[ $i ] ); $j ++ ) {
121
  $auth_method = $auth_methods[ $i ][ $j ];
 
 
 
 
 
 
 
122
  $auth_method_abr = str_replace( ' ', '', $auth_method );
123
  $configured_auth_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
124
  $is_auth_method_selected = ( $configured_auth_method == $auth_method ? true : false );
@@ -128,23 +163,38 @@
128
  ( $is_NC && in_array( $auth_method, $two_factor_methods_NC ) ) ) {
129
  $is_auth_method_av = true;
130
  }
131
-
132
-
133
  $thumbnail_height = $is_auth_method_av && $category == 'free_plan' ? 190 : 160;
134
  $is_image = $auth_method == "" ? 0 :1;
135
 
136
  $form .= '<td style="width:33%;height: 203px;">
137
  <div class="mo2f_thumbnail" id="'.$auth_method_abr.'_thumbnail_2_factor" style="height:' . $thumbnail_height . 'px;border:1px solid ';
138
- $form .= $is_auth_method_selected ? '#48b74b' : '#20b2aa';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  $form .= ';border-top:3px solid ';
140
  $form .= $is_auth_method_selected ? '#48b74b' : '#20b2aa';
141
  $form .= ';">';
 
 
142
  $form .= '<div>
143
  <div class="mo2f_thumbnail_method">
144
  <div style="width: 30%; float:left;">';
145
 
146
  if($is_image){
147
- $form .= '<img src="' . plugins_url( "includes/images/authmethods/" . $auth_method_abr . ".png", dirname(dirname(__FILE__))) . '" style="width: 40px;height: 40px !important; padding: 20px; line-height: 80px;" />';
148
  }
149
 
150
  $form .= '</div>
@@ -160,28 +210,92 @@
160
  $is_auth_method_configured = $Mo2fdbQueries->get_user_detail( 'mo2f_' . $auth_method_abr . '_config_status', $user->ID );
161
 
162
  $form .= '<div style="height:40px;width:100%;position: absolute;bottom: 0;background-color:';
163
- $form .= $is_auth_method_selected ? '#48b74b' : '#20b2aa';
164
-
165
- $form .= ';color:white">';
166
- $check = !$is_customer_registered? true : ($auth_method != "Email Verification"? true : false);
167
- if ( $check ) {
168
- $form .= '<div class="mo2f_configure_2_factor">
169
- <button type="button" id="'.$auth_method_abr.'_configuration" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'configure2factor\');"';
170
- $form .= $can_user_configure_2fa_method ? "" : " disabled ";
171
- $form .= '>';
172
- $form .= $is_auth_method_configured ? 'Reconfigure' : 'Configure';
173
- $form .= '</button></div>';
174
- }
175
- if ( $is_auth_method_configured && ! $is_auth_method_selected ) {
176
- $form .= '<div class="mo2f_set_2_factor">
177
- <button type="button" id="'.$auth_method_abr.'_set_2_factor" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'select2factor\');"';
178
- $form .= $can_user_configure_2fa_method ? "" : " disabled ";
179
- $form .= '>Set as 2-factor</button>
180
- </div>';
181
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
 
183
  $form .= '</div>';
184
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  }
186
  $form .= '</div></div></td>';
187
  }
@@ -192,9 +306,11 @@
192
 
193
  $form .= '</table>';
194
  if( $category!="free_plan")
 
195
  $form .= '<div style="background-color: #f1f1f1;padding:10px">
196
  <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=mo_2fa_upgrade"><i>Click here.</i></a></p>
197
  </div>';
 
198
 
199
  $form .= '</div> <input type="hidden" name="miniorange_save_form_auth_methods_nonce"
200
  value="'. wp_create_nonce( "miniorange-save-form-auth-methods-nonce" ) .'"/>
@@ -348,7 +464,7 @@ function display_customer_registration_forms($user){
348
  });
349
 
350
  jQuery('#mo2f_registration_closed').click(function () {
351
- jQuery('.mo2f_registration_closed_form').submit();
352
  });
353
  </script>
354
 
@@ -356,19 +472,26 @@ function display_customer_registration_forms($user){
356
  }
357
 
358
  function mo2f_show_registration_screen($user){
359
- global $dirName;
360
 
361
- include $dirName . 'controllers/account.php';
362
 
363
  }
364
 
365
  function mo2f_show_2FA_configuration_screen( $user, $selected2FAmethod ) {
366
- global $dirName;
367
  switch ( $selected2FAmethod ) {
368
  case "Google Authenticator":
 
 
 
 
 
 
369
  Miniorange_Authentication::mo2f_get_GA_parameters($user);
370
  mo2f_configure_google_authenticator( $user );
371
- break;
 
372
  case "Authy Authenticator":
373
  mo2f_configure_authy_authenticator( $user );
374
  break;
1
  <?php
2
+
3
+ $setup_dirName = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'setup'.DIRECTORY_SEPARATOR;
4
+ $test_dirName = dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'test'.DIRECTORY_SEPARATOR;
5
+ include $setup_dirName.'setup_google_authenticator.php';
6
+ include $setup_dirName.'setup_google_authenticator_onpremise.php';
7
+ include $setup_dirName.'setup_authy_authenticator.php';
8
+ include $setup_dirName.'setup_kba_questions.php';
9
+ include $setup_dirName.'setup_miniorange_authenticator.php';
10
+ include $setup_dirName.'setup_otp_over_sms.php';
11
+ include $test_dirName.'test_twofa_email_verification.php';
12
+ include $test_dirName.'test_twofa_google_authy_authenticator.php';
13
+ include $test_dirName.'test_twofa_miniorange_qrcode_authentication.php';
14
+ include $test_dirName.'test_twofa_kba_questions.php';
15
+ include $test_dirName.'test_twofa_miniorange_push_notification.php';
16
+ include $test_dirName.'test_twofa_miniorange_soft_token.php';
17
+ include $test_dirName.'test_twofa_otp_over_sms.php';
18
 
19
  function mo2f_decode_2_factor( $selected_2_factor_method, $decode_type ) {
20
 
83
  "OTP Over SMS and Email",
84
  "Hardware Token"
85
  );
 
86
  $two_factor_methods_descriptions = array(
87
  ""=>"<b>All methods in the FREE Plan in addition to the following methods.</b>",
88
  "miniOrange QR Code Authentication" => "Scan the QR code from the account in your miniOrange Authenticator App to login.",
98
  "Hardware Token" => "Enter the One Time Passcode on your Hardware Token to login."
99
  );
100
 
101
+
102
  $two_factor_methods_EC = array_slice( $all_two_factor_methods, 0, 8 );
103
  $two_factor_methods_NC = array_slice( $all_two_factor_methods, 0, 5 );
104
+ if(MO2F_IS_ONPREM or $category != 'free_plan')
105
+ {
106
+ $all_two_factor_methods = array(
107
+ "Security Questions",
108
+ "Google Authenticator",
109
+ "Email Verification",
110
+ "miniOrange QR Code Authentication",
111
+ "miniOrange Soft Token",
112
+ "miniOrange Push Notification",
113
+ "Authy Authenticator",
114
+ "OTP Over SMS",
115
+ "OTP Over Email",
116
+ "OTP Over SMS and Email",
117
+ "Hardware Token"
118
+ );
119
+ $two_factor_methods_descriptions = array(
120
+ ""=>"<b>All methods in the FREE Plan in addition to the following methods.</b>",
121
+ "Security Questions" => "Answer the three security questions you had set, to login.",
122
+ "Google Authenticator" => "Enter the soft token from the account in your <b>Google/Authy/LastPass Authenticator App</b> to login.",
123
+ "Email Verification" => "Accept the verification link sent to your email to login.",
124
+ "miniOrange QR Code Authentication" => "Scan the QR code from the account in your miniOrange Authenticator App to login.",
125
+ "miniOrange Soft Token" => "Enter the soft token from the account in your miniOrange Authenticator App to login.",
126
+ "miniOrange Push Notification" => "Accept a push notification in your miniOrange Authenticator App to login.",
127
+ "Authy Authenticator" => "Enter the soft token from the account in your Authy Authenticator App to login.",
128
+ "OTP Over SMS" => "Enter the One Time Passcode sent to your phone to login.",
129
+ "OTP Over Email" => "Enter the One Time Passcode sent to your email to login.",
130
+ "OTP Over SMS and Email" => "Enter the One Time Passcode sent to your phone and email to login.",
131
+ "Hardware Token" => "Enter the One Time Passcode on your Hardware Token to login."
132
+ );
133
+ }
134
 
135
  $is_customer_registered = $Mo2fdbQueries->get_user_detail( 'user_registration_with_miniorange', $user->ID ) == 'SUCCESS' ? true : false;
 
136
  $can_user_configure_2fa_method = $can_display_admin_features || ( !$can_display_admin_features && $is_customer_registered );
137
  $is_NC = get_option( 'mo2f_is_NC' );
138
  $is_EC = ! $is_NC;
 
139
  $form = '';
140
  $form .= '<form name="f" method="post" action="" id="mo2f_save_' . $category . '_auth_methods_form">
141
  <div id="mo2f_' . $category . '_auth_methods" >
147
  $form .= '<tr>';
148
  for ( $j = 0; $j < count( $auth_methods[ $i ] ); $j ++ ) {
149
  $auth_method = $auth_methods[ $i ][ $j ];
150
+ if(MO2F_IS_ONPREM and $category =='free_plan')
151
+ {
152
+ if($auth_method != 'Email Verification' and $auth_method != 'Security Questions' and $auth_method != 'Google Authenticator')
153
+ {
154
+ //continue;
155
+ }
156
+ }
157
  $auth_method_abr = str_replace( ' ', '', $auth_method );
158
  $configured_auth_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
159
  $is_auth_method_selected = ( $configured_auth_method == $auth_method ? true : false );
163
  ( $is_NC && in_array( $auth_method, $two_factor_methods_NC ) ) ) {
164
  $is_auth_method_av = true;
165
  }
166
+
 
167
  $thumbnail_height = $is_auth_method_av && $category == 'free_plan' ? 190 : 160;
168
  $is_image = $auth_method == "" ? 0 :1;
169
 
170
  $form .= '<td style="width:33%;height: 203px;">
171
  <div class="mo2f_thumbnail" id="'.$auth_method_abr.'_thumbnail_2_factor" style="height:' . $thumbnail_height . 'px;border:1px solid ';
172
+ if(MO2F_IS_ONPREM)
173
+ {
174
+ $iscurrentMethod = 0;
175
+ $currentMethod = get_user_meta($user->ID,'currentMethod',true);
176
+ if($currentMethod == $auth_method)
177
+ $iscurrentMethod = 1;
178
+
179
+ $form .= $iscurrentMethod ? '#48b74b' : '#20b2aa';
180
+ $form .= ';border-top:3px solid ';
181
+ $form .= $iscurrentMethod ? '#48b74b' : '#20b2aa';
182
+ $form .= ';">';
183
+ }
184
+ else
185
+ {
186
+ $form .= $is_auth_method_selected ? '#48b74b' : '#20b2aa';
187
  $form .= ';border-top:3px solid ';
188
  $form .= $is_auth_method_selected ? '#48b74b' : '#20b2aa';
189
  $form .= ';">';
190
+
191
+ }
192
  $form .= '<div>
193
  <div class="mo2f_thumbnail_method">
194
  <div style="width: 30%; float:left;">';
195
 
196
  if($is_image){
197
+ $form .= '<img src="' . plugins_url( "includes/images/authmethods/" . $auth_method_abr . ".png", dirname(dirname(__FILE__ ))) . '" style="width: 40px;height: 40px !important; padding: 20px; line-height: 80px;" />';
198
  }
199
 
200
  $form .= '</div>
210
  $is_auth_method_configured = $Mo2fdbQueries->get_user_detail( 'mo2f_' . $auth_method_abr . '_config_status', $user->ID );
211
 
212
  $form .= '<div style="height:40px;width:100%;position: absolute;bottom: 0;background-color:';
213
+ $iscurrentMethod = 0;
214
+ if(MO2F_IS_ONPREM)
215
+ {
216
+ $currentMethod = get_user_meta($user->ID,'currentMethod',true);
217
+ if($currentMethod == $auth_method)
218
+ $iscurrentMethod = 1;
219
+ $form .= $iscurrentMethod ? '#48b74b' : '#20b2aa';
 
 
 
 
 
 
 
 
 
 
 
220
  }
221
+ else
222
+ $form .= $is_auth_method_selected ? '#48b74b' : '#20b2aa';
223
+ if(MO2F_IS_ONPREM)
224
+ {
225
+ $twofactor_transactions = new Mo2fDB;
226
+ $exceeded = $twofactor_transactions->check_user_limit_exceeded($user->ID);
227
+ if($exceeded){
228
+ $twofactor_registered = get_user_meta($user->ID , 'currentMethod');
229
+ if(empty($twofactor_registered)){
230
+ $can_user_configure_2fa_method = false;
231
+ }
232
+ else{
233
+ $can_user_configure_2fa_method = true;
234
+ }
235
+ }
236
+ else{
237
+ $can_user_configure_2fa_method = true;
238
+ }
239
+ $is_customer_registered = true;
240
+ $user = wp_get_current_user();
241
+ $form .= ';color:white">';
242
+ $is_auth_method_configured = get_user_meta($user->ID,$auth_method,true);
243
+
244
+ $check = $is_customer_registered? true : false;
245
+ $show = 0;
246
+
247
+ if($auth_method == 'Email Verification' || $auth_method == 'Security Questions' || $auth_method == 'Google Authenticator')
248
+ {
249
+ $show = 1;
250
+ }
251
+ if ( $check ) {
252
+ $form .= '<div class="mo2f_configure_2_factor">
253
+ <button type="button" id="'.$auth_method_abr.'_configuration" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'configure2factor\');"';
254
+ $form .= $can_user_configure_2fa_method? "" : " disabled ";
255
+ $form .= $show==1 ? "" : " disabled ";
256
+ $form .= '>';
257
+ if($show)
258
+ $form .= $is_auth_method_configured? 'Reconfigure' : 'Configure';
259
+ else
260
+ $form .= 'Available in cloud solution';
261
+ $form .= '</button></div>';
262
+ }
263
+
264
+ if ( ($is_auth_method_configured && ! $is_auth_method_selected) or MO2F_IS_ONPREM) {
265
+ $form .= '<div class="mo2f_set_2_factor">
266
+ <button type="button" id="'.$auth_method_abr.'_set_2_factor" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'select2factor\');"';
267
+ $form .= $can_user_configure_2fa_method ? "" : " disabled ";
268
+ $form .= $show==1 ? "" : " disabled ";
269
+ if($show == 1 and $is_auth_method_configured and $iscurrentMethod == 0)
270
+ $form .= '>Set as 2-factor</button>
271
+ </div>';
272
+ }
273
 
274
  $form .= '</div>';
275
 
276
+ }
277
+ else
278
+ {
279
+ $form .= ';color:white">';
280
+ $check = !$is_customer_registered? true : ($auth_method != "Email Verification"? true : false);
281
+ if ( $check ) {
282
+ $form .= '<div class="mo2f_configure_2_factor">
283
+ <button type="button" id="'.$auth_method_abr.'_configuration" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'configure2factor\');"';
284
+ $form .= $can_user_configure_2fa_method ? "" : " disabled ";
285
+ $form .= '>';
286
+ $form .= $is_auth_method_configured ? 'Reconfigure' : 'Configure';
287
+ $form .= '</button></div>';
288
+ }
289
+ if ( ($is_auth_method_configured && ! $is_auth_method_selected) or MO2F_IS_ONPREM ) {
290
+ $form .= '<div class="mo2f_set_2_factor">
291
+ <button type="button" id="'.$auth_method_abr.'_set_2_factor" class="mo2f_configure_set_2_factor" onclick="configureOrSet2ndFactor_' . $category . '(\'' . $auth_method_abr . '\', \'select2factor\');"';
292
+ $form .= $can_user_configure_2fa_method ? "" : " disabled ";
293
+ $form .= '>Set as 2-factor</button>
294
+ </div>';
295
+ }
296
+
297
+ $form .= '</div>';
298
+ }
299
  }
300
  $form .= '</div></div></td>';
301
  }
306
 
307
  $form .= '</table>';
308
  if( $category!="free_plan")
309
+ if(current_user_can('administrator')){
310
  $form .= '<div style="background-color: #f1f1f1;padding:10px">
311
  <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=mo_2fa_upgrade"><i>Click here.</i></a></p>
312
  </div>';
313
+ }
314
 
315
  $form .= '</div> <input type="hidden" name="miniorange_save_form_auth_methods_nonce"
316
  value="'. wp_create_nonce( "miniorange-save-form-auth-methods-nonce" ) .'"/>
464
  });
465
 
466
  jQuery('#mo2f_registration_closed').click(function () {
467
+ jQuery('.mo2f_registration_closed_form').submit();
468
  });
469
  </script>
470
 
472
  }
473
 
474
  function mo2f_show_registration_screen($user){
475
+ global $mo2f_dirName;
476
 
477
+ include $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'account.php';
478
 
479
  }
480
 
481
  function mo2f_show_2FA_configuration_screen( $user, $selected2FAmethod ) {
482
+ global $mo2f_dirName;
483
  switch ( $selected2FAmethod ) {
484
  case "Google Authenticator":
485
+ if(get_site_option('is_onprem')){
486
+ include_once dirname( __FILE__ ) . DIRECTORY_SEPARATOR. 'gaonprem.php';
487
+ $obj = new Google_auth_onpremise();
488
+ $obj->mo_GAuth_get_details();
489
+ }
490
+ else{
491
  Miniorange_Authentication::mo2f_get_GA_parameters($user);
492
  mo2f_configure_google_authenticator( $user );
493
+ }
494
+ break;
495
  case "Authy Authenticator":
496
  mo2f_configure_authy_authenticator( $user );
497
  break;
handler/twofa/two_fa_constants.php CHANGED
@@ -216,6 +216,9 @@ class Mo2fConstants {
216
  case 'COMPLETED_TEST':
217
  Return mo2f_lt( 'You have successfully completed the test.' );
218
  break;
 
 
 
219
  case 'INVALID_ENTRY':
220
  Return mo2f_lt( 'All the fields are required. Please enter valid entries.' );
221
  break;
@@ -249,6 +252,9 @@ class Mo2fConstants {
249
  case 'ERROR_DURING_PROCESS':
250
  Return mo2f_lt( 'An error occured while processing your request. Please Try again.' );
251
  break;
 
 
 
252
  case 'ERROR_WHILE_SENDING_SMS':
253
  Return mo2f_lt( 'There was an error in sending sms. Please click on Resend OTP to try again.' );
254
  break;
@@ -396,6 +402,12 @@ class Mo2fConstants {
396
  case 'ERROR_CREATE_ACC_OTP':
397
  Return mo2f_lt( 'An error occured while creating your account. Please try again by sending OTP again.' );
398
  break;
 
 
 
 
 
 
399
  default:
400
  return $text;
401
  }
@@ -403,4 +415,4 @@ class Mo2fConstants {
403
  }
404
 
405
  new Mo2fConstants;
406
- ?>
216
  case 'COMPLETED_TEST':
217
  Return mo2f_lt( 'You have successfully completed the test.' );
218
  break;
219
+ case 'INVALID_EMAIL_VER_REQ':
220
+ Return mo2f_lt( 'Invalid request. test case failed.');
221
+ break;
222
  case 'INVALID_ENTRY':
223
  Return mo2f_lt( 'All the fields are required. Please enter valid entries.' );
224
  break;
252
  case 'ERROR_DURING_PROCESS':
253
  Return mo2f_lt( 'An error occured while processing your request. Please Try again.' );
254
  break;
255
+ case 'ERROR_DURING_PROCESS_EMAIL':
256
+ Return mo2f_lt( 'An error occured while processing your request. Please check your SMTP server is configured.' );
257
+ break;
258
  case 'ERROR_WHILE_SENDING_SMS':
259
  Return mo2f_lt( 'There was an error in sending sms. Please click on Resend OTP to try again.' );
260
  break;
402
  case 'ERROR_CREATE_ACC_OTP':
403
  Return mo2f_lt( 'An error occured while creating your account. Please try again by sending OTP again.' );
404
  break;
405
+ case 'LOGIN_WITH_2ND_FACTOR':
406
+ Return mo2f_lt( 'Please disable 2FA prompt on WP login page to enable Login with 2nd facor only.' );
407
+ break;
408
+ case 'USER_LIMIT_EXCEEDED':
409
+ Return mo2f_lt( 'Your limit of 3 users has exceeded. Please upgrade to premium plans for more users.' );
410
+ break;
411
  default:
412
  return $text;
413
  }
415
  }
416
 
417
  new Mo2fConstants;
418
+ ?>
handler/twofa/two_fa_login.php CHANGED
@@ -26,26 +26,36 @@ include dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'controllers'.DI
26
  class Miniorange_Mobile_Login {
27
 
28
  function mo2fa_default_login( $user, $username, $password ) {
29
-
30
  global $Mo2fdbQueries;
31
  $currentuser = wp_authenticate_username_password( $user, $username, $password );
32
  if ( is_wp_error( $currentuser ) ) {
33
  return $currentuser;
34
  } else {
35
-
36
- $this->miniorange_login_start_session();
37
- $pass2fa_login_session = new Miniorange_Password_2Factor_Login();
38
- $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
39
-
 
 
40
  if(is_null($session_id)) {
41
- $session_id=$pass2fa_login_session->create_session();
42
  }
 
 
 
 
 
 
 
 
 
43
  $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $currentuser->ID );
44
  $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;
45
  if ( $mo2f_configured_2FA_method ) {
46
  $mo2f_user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $currentuser->ID );
47
  $mo2f_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $currentuser->ID );
48
-
49
  if ( $mo2f_user_email && $mo2f_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) { //checking if user has configured any 2nd factor method
50
  MO2f_Utility::set_user_values( $session_id, "mo2f_login_message", '<strong>ERROR</strong>: Login with password is disabled for you. Please Login using your phone.' );
51
  $this->mo_auth_show_error_message();
@@ -67,10 +77,9 @@ class Miniorange_Mobile_Login {
67
  }
68
  }
69
 
70
- function mo_auth_show_error_message() {
71
  remove_filter( 'login_message', array( $this, 'mo_auth_success_message' ) );
72
  add_filter( 'login_message', array( $this, 'mo_auth_error_message' ) );
73
-
74
  }
75
 
76
  function mo2f_redirectto_wp_login() {
@@ -87,7 +96,6 @@ class Miniorange_Mobile_Login {
87
  } else {
88
  MO2f_Utility::set_user_values( $session_id, "mo_2factor_login_status", 'MO_2_FACTOR_SHOW_USERPASS_LOGIN_FORM' );
89
  }
90
-
91
  }
92
 
93
  function mo2f_verify_and_authenticate_userlogin( $user, $redirect_to = null, $session_id=null ) {
@@ -150,23 +158,37 @@ class Miniorange_Mobile_Login {
150
  }
151
 
152
  function custom_login_enqueue_scripts() {
153
-
154
  wp_enqueue_script( 'jquery' );
155
- wp_enqueue_script( 'bootstrap_script', plugins_url( 'includes/js/bootstrap.min.js', dirname(dirname(__FILE__ ))) );
 
 
156
  }
157
 
158
  function mo_2_factor_hide_login() {
159
- wp_register_style( 'hide-login', plugins_url( 'includes/css/hide-login.css?version=5.1.21', dirname(dirname(__FILE__ )) ) );
160
- wp_register_style( 'bootstrap', plugins_url( 'includes/css/bootstrap.min.css?version=5.1.21', dirname(dirname(__FILE__ )) ) );
 
 
 
 
 
161
  wp_enqueue_style( 'hide-login' );
162
  wp_enqueue_style( 'bootstrap' );
163
 
164
  }
165
 
166
  function mo_auth_success_message() {
167
- //if the php session folder has insufficient permissions, cookies to be used
168
  $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
169
  $message = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_login_message', $session_id );
 
 
 
 
 
 
 
 
170
  return "<div> <p class='message'>" . $message . "</p></div>";
171
  }
172
 
@@ -175,6 +197,16 @@ class Miniorange_Mobile_Login {
175
  //if the php session folder has insufficient permissions, cookies to be used
176
  $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
177
  $message = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_login_message', $session_id );
 
 
 
 
 
 
 
 
 
 
178
  return "<div id='" . $id . "'> <p>" . $message . "</p></div>";
179
  }
180
 
@@ -194,9 +226,23 @@ class Miniorange_Mobile_Login {
194
 
195
  if ( get_option( 'mo2f_enable_login_with_2nd_factor' ) ) { //login with phone overwrite default login form
196
  //if the php session folder has insufficient permissions, cookies to be used
197
-
198
  $login_status_phone_enable = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo_2factor_login_status' ,$session_id_encrypt);
199
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  if ( $login_status_phone_enable == 'MO_2_FACTOR_LOGIN_WHEN_PHONELOGIN_ENABLED' && isset( $_POST['miniorange_login_nonce'] ) && wp_verify_nonce( $_POST['miniorange_login_nonce'], 'miniorange-2-factor-login-nonce' ) ) {
201
  $this->mo_2_factor_show_login_with_password_when_phonelogin_enabled();
202
  $this->mo_2_factor_show_wp_login_form_when_phonelogin_enabled();
@@ -207,11 +253,10 @@ class Miniorange_Mobile_Login {
207
  jQuery('#user_login').val(<?php echo "'" . $mo2f_user_login . "'"; ?>);
208
  </script><?php
209
  } else {
210
-
211
  $this->mo_2_factor_show_login();
212
  $this->mo_2_factor_show_wp_login_form();
213
  }
214
- } else { //Login with phone is alogin with default login form
215
  $this->mo_2_factor_show_login();
216
  $this->mo_2_factor_show_wp_login_form();
217
  }
@@ -219,7 +264,7 @@ class Miniorange_Mobile_Login {
219
  }
220
 
221
  function mo_2_factor_show_login_with_password_when_phonelogin_enabled() {
222
- wp_register_style( 'show-login', plugins_url( 'includes/css/show-login.css?version=5.1.21', dirname(dirname(__FILE__ )) ) );
223
  wp_enqueue_style( 'show-login' );
224
  }
225
 
@@ -240,11 +285,14 @@ class Miniorange_Mobile_Login {
240
  }
241
 
242
  function mo_2_factor_show_login() {
243
-
 
 
 
244
  if ( get_option( 'mo2f_enable_login_with_2nd_factor' ) ) {
245
- wp_register_style( 'show-login',plugins_url( 'includes/css/hide-login-form.css?version=5.1.21', dirname(dirname(__FILE__ ))) );
246
  } else {
247
- wp_register_style( 'show-login', plugins_url( 'includes/css/show-login.css?version=5.1.21', dirname(dirname(__FILE__ ))) );
248
  }
249
  wp_enqueue_style( 'show-login' );
250
  }
@@ -261,27 +309,42 @@ class Miniorange_Mobile_Login {
261
  <h2 class="login_with_2factor_h2"><?php echo mo2f_lt( 'or' ); ?></h2>
262
  </div>
263
  <?php } ?>
 
 
264
  <div class="mo2f-button-container" id="mo2f_button_container">
265
  <input type="text" name="mo2fa_usernamekey" id="mo2fa_usernamekey" autofocus="true"
266
  placeholder="<?php echo mo2f_lt( 'Username' ); ?>"/>
267
  <p>
268
-
 
 
 
 
 
 
 
 
 
269
  <input type="button" name="miniorange_login_submit" style="width:100% !important;"
270
  onclick="mouserloginsubmit();" id="miniorange_login_submit"
271
- class="miniorange-button button-add"
272
  value="<?php echo mo2f_lt( 'Login with 2nd factor' ); ?>"/>
273
  </p>
 
274
  <?php if ( ! $mo2f_enable_login_with_2nd_factor ) { ?><br><br><?php } ?>
275
  </div>
276
  </div>
277
 
278
  <script>
279
-
280
  jQuery(window).scrollTop(jQuery('#mo2f_button_container').offset().top);
281
 
282
  function mouserloginsubmit() {
283
  var username = jQuery('#mo2fa_usernamekey').val();
 
 
284
  document.getElementById("mo2f_show_qrcode_loginform").elements[0].value = username;
 
 
285
  jQuery('#mo2f_show_qrcode_loginform').submit();
286
 
287
  }
@@ -317,6 +380,7 @@ class Miniorange_Mobile_Login {
317
  </form>
318
  <form name="f" id="mo2f_show_qrcode_loginform" method="post" action="" hidden>
319
  <input type="text" name="mo2fa_username" id="mo2fa_username" hidden/>
 
320
  <input type="hidden" name="miniorange_login_nonce"
321
  value="<?php echo wp_create_nonce( 'miniorange-2-factor-login-nonce' ); ?>"/>
322
  <input type="hidden" id="sessid" name="session_id"
@@ -336,4 +400,4 @@ class Miniorange_Mobile_Login {
336
  }
337
  }
338
 
339
- ?>
26
  class Miniorange_Mobile_Login {
27
 
28
  function mo2fa_default_login( $user, $username, $password ) {
29
+
30
  global $Mo2fdbQueries;
31
  $currentuser = wp_authenticate_username_password( $user, $username, $password );
32
  if ( is_wp_error( $currentuser ) ) {
33
  return $currentuser;
34
  } else {
35
+ if(MO2F_IS_ONPREM and (!get_option('mo2f_login_option') or get_option('mo2f_enable_login_with_2nd_factor')))
36
+ {
37
+ $mo2f_configured_2FA_method = get_user_meta($currentuser->ID,'currentMethod',true);
38
+ $attributes = isset( $_POST['miniorange_rba_attribures'] ) ? $_POST['miniorange_rba_attribures'] : null;
39
+ $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
40
+ $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;
41
+ $handleSecondFactor = new Miniorange_Password_2Factor_Login();
42
  if(is_null($session_id)) {
43
+ $session_id = $handleSecondFactor->create_session();
44
  }
45
+
46
+ $key = get_option('mo2f_customer_token');
47
+ $otp_token = '';
48
+ $error=$handleSecondFactor->miniorange_initiate_2nd_factor( $currentuser, $attributes, $redirect_to, $otp_token, $session_id );
49
+
50
+ }
51
+ $this->miniorange_login_start_session();
52
+ $pass2fa_login_session = new Miniorange_Password_2Factor_Login();
53
+ $session_id=$pass2fa_login_session->create_session();
54
  $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $currentuser->ID );
55
  $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;
56
  if ( $mo2f_configured_2FA_method ) {
57
  $mo2f_user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $currentuser->ID );
58
  $mo2f_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $currentuser->ID );
 
59
  if ( $mo2f_user_email && $mo2f_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) { //checking if user has configured any 2nd factor method
60
  MO2f_Utility::set_user_values( $session_id, "mo2f_login_message", '<strong>ERROR</strong>: Login with password is disabled for you. Please Login using your phone.' );
61
  $this->mo_auth_show_error_message();
77
  }
78
  }
79
 
80
+ function mo_auth_show_error_message($value = null) {
81
  remove_filter( 'login_message', array( $this, 'mo_auth_success_message' ) );
82
  add_filter( 'login_message', array( $this, 'mo_auth_error_message' ) );
 
83
  }
84
 
85
  function mo2f_redirectto_wp_login() {
96
  } else {
97
  MO2f_Utility::set_user_values( $session_id, "mo_2factor_login_status", 'MO_2_FACTOR_SHOW_USERPASS_LOGIN_FORM' );
98
  }
 
99
  }
100
 
101
  function mo2f_verify_and_authenticate_userlogin( $user, $redirect_to = null, $session_id=null ) {
158
  }
159
 
160
  function custom_login_enqueue_scripts() {
 
161
  wp_enqueue_script( 'jquery' );
162
+ $bootstrappath = plugins_url( 'includes/css/bootstrap.min.css?version='.MO2F_VERSION.'', dirname(dirname(__FILE__)) );
163
+ $bootstrappath = str_replace('/handler/includes/css', '/includes/css', $bootstrappath);
164
+ wp_enqueue_style( 'bootstrap_script', $bootstrappath );
165
  }
166
 
167
  function mo_2_factor_hide_login() {
168
+ $bootstrappath = plugins_url( 'includes/css/bootstrap.min.css?version='.MO2F_VERSION.'', dirname(dirname(__FILE__)) );
169
+ $bootstrappath = str_replace('/handler/includes/css', '/includes/css', $bootstrappath);
170
+ $hidepath = plugins_url( 'includes/css/hide-login-form.css?version=5.1.21', dirname(dirname(__FILE__)) );
171
+ $hidepath = str_replace('/handler/includes/css', '/includes/css', $hidepath);
172
+
173
+ wp_register_style( 'hide-login', $hidepath );
174
+ wp_register_style( 'bootstrap', $bootstrappath );
175
  wp_enqueue_style( 'hide-login' );
176
  wp_enqueue_style( 'bootstrap' );
177
 
178
  }
179
 
180
  function mo_auth_success_message() {
181
+ $message = isset($_SESSION['mo2f_login_message']) ? $_SESSION['mo2f_login_message'] : '';
182
  $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
183
  $message = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_login_message', $session_id );
184
+ //if the php session folder has insufficient permissions, cookies to be used
185
+
186
+
187
+ if($message == '')
188
+ {
189
+ $message = 'Please login into your account using password.';
190
+ }
191
+
192
  return "<div> <p class='message'>" . $message . "</p></div>";
193
  }
194
 
197
  //if the php session folder has insufficient permissions, cookies to be used
198
  $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
199
  $message = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_login_message', $session_id );
200
+ //if the php session folder has insufficient permissions, cookies to be used
201
+ //$message = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_login_message' );
202
+ if($message=='')
203
+ {
204
+ $message = 'Invalid Username';
205
+ }
206
+ if(get_option('mo_wpns_activate_recaptcha_for_login'))
207
+ { //test
208
+ $message = 'Invalid Username or recaptcha';
209
+ }
210
  return "<div id='" . $id . "'> <p>" . $message . "</p></div>";
211
  }
212
 
226
 
227
  if ( get_option( 'mo2f_enable_login_with_2nd_factor' ) ) { //login with phone overwrite default login form
228
  //if the php session folder has insufficient permissions, cookies to be used
 
229
  $login_status_phone_enable = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo_2factor_login_status' ,$session_id_encrypt);
230
+
231
+ if(MO2F_IS_ONPREM)
232
+ {
233
+ $userName = isset($_POST['mo2fa_username']) ? $_POST['mo2fa_username'] : '';
234
+
235
+ if(!empty($userName))
236
+ {
237
+ $user = get_user_by('login',$userName);
238
+ if($user)
239
+ {
240
+ $currentMethod = get_user_meta($user->ID, 'currentMethod', true);
241
+ if($currentMethod == 'None' or $currentMethod == '')
242
+ $login_status_phone_enable = 'MO_2_FACTOR_LOGIN_WHEN_PHONELOGIN_ENABLED';
243
+ }
244
+ }
245
+ }
246
  if ( $login_status_phone_enable == 'MO_2_FACTOR_LOGIN_WHEN_PHONELOGIN_ENABLED' && isset( $_POST['miniorange_login_nonce'] ) && wp_verify_nonce( $_POST['miniorange_login_nonce'], 'miniorange-2-factor-login-nonce' ) ) {
247
  $this->mo_2_factor_show_login_with_password_when_phonelogin_enabled();
248
  $this->mo_2_factor_show_wp_login_form_when_phonelogin_enabled();
253
  jQuery('#user_login').val(<?php echo "'" . $mo2f_user_login . "'"; ?>);
254
  </script><?php
255
  } else {
 
256
  $this->mo_2_factor_show_login();
257
  $this->mo_2_factor_show_wp_login_form();
258
  }
259
+ } else { //Login with phone is alogin with default login form
260
  $this->mo_2_factor_show_login();
261
  $this->mo_2_factor_show_wp_login_form();
262
  }
264
  }
265
 
266
  function mo_2_factor_show_login_with_password_when_phonelogin_enabled() {
267
+ wp_register_style( 'show-login', plugins_url( 'includes/css/show-login.css?version=5.1.21', dirname(dirname(__FILE__ ))) );
268
  wp_enqueue_style( 'show-login' );
269
  }
270
 
285
  }
286
 
287
  function mo_2_factor_show_login() {
288
+ $hidepath = plugins_url( 'includes/css/hide-login-form.css?version=5.1.21', dirname(dirname(__FILE__)) );
289
+
290
+ $showpath = plugins_url( 'includes/css/show-login.css?version=5.1.21', dirname(dirname(__FILE__ )));
291
+
292
  if ( get_option( 'mo2f_enable_login_with_2nd_factor' ) ) {
293
+ wp_register_style( 'show-login', $hidepath );
294
  } else {
295
+ wp_register_style( 'show-login', $showpath );
296
  }
297
  wp_enqueue_style( 'show-login' );
298
  }
309
  <h2 class="login_with_2factor_h2"><?php echo mo2f_lt( 'or' ); ?></h2>
310
  </div>
311
  <?php } ?>
312
+
313
+ <br>
314
  <div class="mo2f-button-container" id="mo2f_button_container">
315
  <input type="text" name="mo2fa_usernamekey" id="mo2fa_usernamekey" autofocus="true"
316
  placeholder="<?php echo mo2f_lt( 'Username' ); ?>"/>
317
  <p>
318
+ <?php
319
+ if(get_option('mo_wpns_activate_recaptcha_for_login'))
320
+ {
321
+
322
+ echo "<script src='".MoWpnsConstants::RECAPTCHA_URL."'></script>";
323
+ echo '<div class="g-recaptcha" data-sitekey="'.get_option("mo_wpns_recaptcha_site_key").'"></div>';
324
+ echo '<style>#login{ width:349px;padding:2% 0 0; }.g-recaptcha{margin-bottom:5%;}#loginform{padding-bottom:20px;}</style>';
325
+ }
326
+
327
+ ?>
328
  <input type="button" name="miniorange_login_submit" style="width:100% !important;"
329
  onclick="mouserloginsubmit();" id="miniorange_login_submit"
330
+ class="button button-primary button-large"
331
  value="<?php echo mo2f_lt( 'Login with 2nd factor' ); ?>"/>
332
  </p>
333
+ <br><br><br>
334
  <?php if ( ! $mo2f_enable_login_with_2nd_factor ) { ?><br><br><?php } ?>
335
  </div>
336
  </div>
337
 
338
  <script>
 
339
  jQuery(window).scrollTop(jQuery('#mo2f_button_container').offset().top);
340
 
341
  function mouserloginsubmit() {
342
  var username = jQuery('#mo2fa_usernamekey').val();
343
+ var recap = jQuery('#g-recaptcha-response').val();
344
+
345
  document.getElementById("mo2f_show_qrcode_loginform").elements[0].value = username;
346
+ document.getElementById("mo2f_show_qrcode_loginform").elements[1].value = recap;
347
+
348
  jQuery('#mo2f_show_qrcode_loginform').submit();
349
 
350
  }
380
  </form>
381
  <form name="f" id="mo2f_show_qrcode_loginform" method="post" action="" hidden>
382
  <input type="text" name="mo2fa_username" id="mo2fa_username" hidden/>
383
+ <input type="text" name="g-recaptcha-response" id = 'g-recaptcha-response' hidden/>
384
  <input type="hidden" name="miniorange_login_nonce"
385
  value="<?php echo wp_create_nonce( 'miniorange-2-factor-login-nonce' ); ?>"/>
386
  <input type="hidden" id="sessid" name="session_id"
400
  }
401
  }
402
 
403
+ ?>
handler/twofa/two_fa_pass2login.php CHANGED
@@ -1,4 +1,4 @@
1
- <?Php
2
  /** miniOrange enables user to log in through mobile authentication as an additional layer of security over password.
3
  * Copyright (C) 2015 miniOrange
4
  *
@@ -22,14 +22,15 @@
22
  * Contains Request Calls to Customer service.
23
  **/
24
 
25
- include dirname(__FILE__).DIRECTORY_SEPARATOR.'two_fa_login.php';
26
  class Miniorange_Password_2Factor_Login {
27
 
28
  private $mo2f_kbaquestions;
29
  private $mo2f_userID;
30
  private $mo2f_rbastatus;
31
  private $mo2f_transactionid;
32
-
 
33
  public function miniorange_pass2login_redirect() {
34
  do_action('mo2f_network_init');
35
  global $Mo2fdbQueries;
@@ -50,7 +51,6 @@ class Miniorange_Password_2Factor_Login {
50
  $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
51
  return $error;
52
  } else {
53
-
54
  $this->miniorange_pass2login_start_session();
55
  $mobile_login = new Miniorange_Mobile_Login();
56
  //validation and sanitization
@@ -62,8 +62,7 @@ class Miniorange_Password_2Factor_Login {
62
  } else {
63
  $username = sanitize_text_field( $_POST['mo2fa_username'] );
64
  }
65
- if ( username_exists( $username ) ) { /*if username exists in wp site */
66
-
67
  $user = new WP_User( $username );
68
  $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;
69
  MO2f_Utility::set_user_values($session_id, 'mo2f_current_user_id', $user->ID );
@@ -75,19 +74,48 @@ class Miniorange_Password_2Factor_Login {
75
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
76
  $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID );
77
  $kba_configuration_status = $Mo2fdbQueries->get_user_detail( 'mo2f_SecurityQuestions_config_status', $user->ID );
78
-
 
 
 
 
 
 
 
 
79
  if ( $mo2f_configured_2FA_method ) {
80
- if ( $email && $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
81
  if ( MO2f_Utility::check_if_request_is_from_mobile_device( $_SERVER['HTTP_USER_AGENT'] ) && $kba_configuration_status ) {
82
  $this->mo2f_pass2login_kba_verification( $user->ID, $redirect_to, $session_id );
83
  } else {
 
84
  $mo2f_second_factor = mo2f_get_user_2ndfactor( $user );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  if ( $mo2f_second_factor == 'MOBILE AUTHENTICATION' ) {
86
  $this->mo2f_pass2login_mobile_verification( $user, $redirect_to, $session_id );
87
  } else if ( $mo2f_second_factor == 'PUSH NOTIFICATIONS' || $mo2f_second_factor == 'OUT OF BAND EMAIL' ) {
88
  $this->mo2f_pass2login_push_oobemail_verification( $user, $mo2f_second_factor, $redirect_to, $session_id );
89
- } else if ( $mo2f_second_factor == 'SOFT TOKEN' || $mo2f_second_factor == 'SMS' || $mo2f_second_factor == 'PHONE VERIFICATION' || $mo2f_second_factor == 'GOOGLE AUTHENTICATOR' ) {
90
-
 
 
 
91
  $this->mo2f_pass2login_otp_verification( $user, $mo2f_second_factor, $redirect_to, $session_id );
92
  } else if ( $mo2f_second_factor == 'KBA' ) {
93
  $this->mo2f_pass2login_kba_verification( $user->ID, $redirect_to, $session_id );
@@ -99,26 +127,85 @@ class Miniorange_Password_2Factor_Login {
99
  }
100
  } else {
101
  MO2f_Utility::set_user_values($session_id, 'mo2f_login_message', 'Please login into your account using password.' );
102
- $mobile_login->mo_auth_show_success_message();
 
103
  $mobile_login->mo2f_redirectto_wp_login();
104
  }
105
- } else {
106
  MO2f_Utility::set_user_values( $session_id, "mo2f_login_message", 'Please login into your account using password.' );
107
- $mobile_login->mo_auth_show_success_message();
 
108
  $mobile_login->mo2f_redirectto_wp_login();
109
-
110
  }
111
  } else {
112
  $mobile_login->remove_current_activity($session_id);
113
  MO2f_Utility::set_user_values( $session_id, "mo2f_login_message", 'Invalid Username.' );
114
- $mobile_login->mo_auth_show_error_message();
115
  }
116
  }
117
  }
118
 
119
  }
120
-
121
- if ( isset( $_POST['mo2f_trust_device_confirm_nonce'] ) ) { /*register device as rba profile */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  $nonce = $_POST['mo2f_trust_device_confirm_nonce'];
123
  if ( ! wp_verify_nonce( $nonce, 'miniorange-2-factor-trust-device-confirm-nonce' ) ) {
124
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
@@ -211,13 +298,14 @@ class Miniorange_Password_2Factor_Login {
211
  $this->mo2f_pass2login_kba_verification( $user_id, $redirect_to,$session_id_encrypt );
212
  }
213
  }else if ( isset( $_POST['miniorange_kba_nonce'] ) ) { /*check kba validation*/
214
-
215
  $nonce = $_POST['miniorange_kba_nonce'];
216
  if ( ! wp_verify_nonce( $nonce, 'miniorange-2-factor-kba-nonce' ) ) {
217
  $error = new WP_Error();
218
  $error->add( 'empty_username', __( '<strong>ERROR</strong>: Invalid Request.' ) );
219
  return $error;
220
- } else {
 
 
221
  $this->miniorange_pass2login_start_session();
222
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
223
  $user_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_current_user_id',$session_id_encrypt );
@@ -230,12 +318,12 @@ class Miniorange_Password_2Factor_Login {
230
  }
231
  $otpToken = array();
232
  $kba_questions = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo_2_factor_kba_questions',$session_id_encrypt );
 
233
  $otpToken[0] = $kba_questions[0];
234
  $otpToken[1] = sanitize_text_field( $_POST['mo2f_answer_1'] );
235
  $otpToken[2] = $kba_questions[1];
236
  $otpToken[3] = sanitize_text_field( $_POST['mo2f_answer_2'] );
237
  $check_trust_device = isset( $_POST['mo2f_trust_device'] ) ? $_POST['mo2f_trust_device'] : 'false';
238
-
239
  //if the php session folder has insufficient permissions, cookies to be used
240
  $mo2f_login_transaction_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_transactionId', $session_id_encrypt );
241
 
@@ -264,15 +352,28 @@ class Miniorange_Password_2Factor_Login {
264
  $this->remove_current_activity($session_id_encrypt);
265
  return new WP_Error( 'invalid_username', __( '<strong>ERROR</strong>: Please try again..' ) );
266
  }
267
- }
268
-
269
- }else if ( isset( $_POST['miniorange_mobile_validation_nonce'] ) ) { /*check mobile validation */
 
270
  $nonce = $_POST['miniorange_mobile_validation_nonce'];
271
  if ( ! wp_verify_nonce( $nonce, 'miniorange-2-factor-mobile-validation-nonce' ) ) {
272
  $error = new WP_Error();
273
  $error->add( 'empty_username', __( '<strong>ERROR</strong>: Invalid Request.' ) );
274
  return $error;
275
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
276
  $this->miniorange_pass2login_start_session();
277
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
278
  //if the php session folder has insufficient permissions, cookies to be used
@@ -281,7 +382,10 @@ class Miniorange_Password_2Factor_Login {
281
  $checkMobileStatus = new Two_Factor_Setup();
282
  $content = $checkMobileStatus->check_mobile_status( $mo2f_login_transaction_id );
283
  $response = json_decode( $content, true );
284
-
 
 
 
285
  if ( json_last_error() == JSON_ERROR_NONE ) {
286
  if ( $response['status'] == 'SUCCESS' ) {
287
  if ( get_option( 'mo2f_remember_device' ) ) {
@@ -309,6 +413,7 @@ class Miniorange_Password_2Factor_Login {
309
  $this->miniorange_pass2login_start_session();
310
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
311
  $this->remove_current_activity($session_id_encrypt);
 
312
  }
313
  }else if ( isset( $_POST['miniorange_forgotphone'] ) ) { /*Click on the link of forgotphone */
314
  $nonce = $_POST['miniorange_forgotphone'];
@@ -386,15 +491,14 @@ class Miniorange_Password_2Factor_Login {
386
  $redirect_to = isset( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : null;
387
  $softtoken = '';
388
  $user_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_current_user_id',$session_id_encrypt );
389
- $attempts=get_user_meta( $user_id, 'mo2f_user_login_attempts', true );
 
390
  if ( MO2f_utility::mo2f_check_empty_or_null( $_POST['mo2fa_softtoken'] ) ) {
391
  if($attempts>1 || $attempts=='disabled')
392
  {
393
- if(get_option( 'mo2f_enable_brute_force' )){
394
- update_user_meta( $user_id , 'mo2f_user_login_attempts', $attempts-1 );
395
- }
396
- $mo2fa_login_message = 'Please enter OTP to proceed.';
397
- $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to,null,$session_id_encrypt );
398
  }else{
399
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
400
  $this->remove_current_activity($session_id_encrypt);
@@ -406,16 +510,15 @@ class Miniorange_Password_2Factor_Login {
406
  if ( ! MO2f_utility::mo2f_check_number_length( $softtoken ) ) {
407
  if($attempts>1|| $attempts=='disabled')
408
  {
409
- if(get_option( 'mo2f_enable_brute_force' )){
410
- update_user_meta( $user_id , 'mo2f_user_login_attempts', $attempts-1 );
411
- }
412
  $mo2fa_login_message = 'Invalid OTP. Only digits within range 4-8 are allowed. Please try again.';
413
  $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to,null,$session_id_encrypt );
414
 
415
  }else{
416
- $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
417
- $this->remove_current_activity($session_id_encrypt);
418
- return new WP_Error( 'limit_exceeded', '<strong>ERROR</strong>: Number of attempts exceeded.');
 
419
  }
420
  }
421
  }
@@ -438,7 +541,7 @@ class Miniorange_Password_2Factor_Login {
438
  $content = json_decode( $customer->validate_otp_token( 'SOFT TOKEN', $user_email, null, $softtoken, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
439
  } else if ( isset( $mo2fa_login_status ) && $mo2fa_login_status == 'MO_2_FACTOR_CHALLENGE_GOOGLE_AUTHENTICATION' ) {
440
 
441
- $content = json_decode( $customer->validate_otp_token( 'GOOGLE AUTHENTICATOR', $user_email, null, $softtoken, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
442
 
443
  } else {
444
  $this->remove_current_activity($session_id_encrypt);
@@ -446,6 +549,7 @@ class Miniorange_Password_2Factor_Login {
446
  }
447
 
448
  if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) {
 
449
  if ( get_option( 'mo2f_remember_device' ) ) {
450
  $mo2fa_login_status = 'MO_2_FACTOR_REMEMBER_TRUSTED_DEVICE';
451
  $this->miniorange_pass2login_form_fields( $mo2fa_login_status, null, $redirect_to,null,$session_id_encrypt );
@@ -455,14 +559,13 @@ class Miniorange_Password_2Factor_Login {
455
  } else {
456
  if($attempts>1 || $attempts=='disabled')
457
  {
458
- if(get_option( 'mo2f_enable_brute_force' )){
459
- update_user_meta( $user_id , 'mo2f_user_login_attempts', $attempts-1 );
460
- }
461
  $message = $mo2fa_login_status == 'MO_2_FACTOR_CHALLENGE_SOFT_TOKEN' ? 'You have entered an invalid OTP.<br>Please click on <b>Sync Time</b> in the miniOrange Authenticator app to sync your phone time with the miniOrange servers and try again.' : 'Invalid OTP. Please try again.';
462
  $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $message, $redirect_to,null,$session_id_encrypt );
463
  }else{
464
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
465
  $this->remove_current_activity($session_id_encrypt);
 
466
  return new WP_Error( 'limit_exceeded', '<strong>ERROR</strong>: Number of attempts exceeded.');
467
  }
468
  }
@@ -501,13 +604,22 @@ class Miniorange_Password_2Factor_Login {
501
 
502
  $attributes = isset( $_POST['miniorange_rba_attribures'] ) ? $_POST['miniorange_rba_attribures'] : null;
503
  $redirect_to = isset( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : null;
504
- $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
505
  $this->miniorange_initiate_2nd_factor( $currentuser, $attributes, $redirect_to,$session_id );
506
  }
507
  }
508
  }
509
 
510
-
 
 
 
 
 
 
 
 
 
511
  function remove_current_activity($session_id) {
512
  global $Mo2fdbQueries;
513
  $session_variables = array(
@@ -580,13 +692,28 @@ class Miniorange_Password_2Factor_Login {
580
  }
581
 
582
  function mo2f_pass2login_kba_verification( $user_id, $redirect_to, $session_id ) {
583
- global $Mo2fdbQueries;
 
584
  $user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user_id );
585
-
586
- if(is_null($session_id)) {
587
  $session_id=$this->create_session();
588
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
 
 
590
  $challengeKba = new Customer_Setup();
591
  $content = $challengeKba->send_otp_token( $user_email, 'KBA', get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) );
592
  $response = json_decode( $content, true );
@@ -616,7 +743,7 @@ class Miniorange_Password_2Factor_Login {
616
 
617
  return $error;
618
  }
619
-
620
  }
621
 
622
  function miniorange_pass2login_form_fields( $mo2fa_login_status = null, $mo2fa_login_message = null, $redirect_to = null, $qrCode = null, $session_id_encrypt ) {
@@ -650,13 +777,23 @@ class Miniorange_Password_2Factor_Login {
650
  exit;
651
  } else if ( $this->miniorange_pass2login_check_kba_status( $login_status ) ) { // for Kba
652
  $kbaquestions = $this->mo2f_kbaquestions ? $this->mo2f_kbaquestions : MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo_2_factor_kba_questions',$session_id_encrypt );
 
 
 
 
 
 
653
  mo2f_get_kba_authentication_prompt( $login_message, $redirect_to, $session_id_encrypt, $kbaquestions );
 
654
  exit;
655
  } else if ( $this->miniorange_pass2login_check_trusted_device_status( $login_status ) ) { // trusted device
656
  mo2f_get_device_form( $redirect_to, $session_id_encrypt );
657
  exit;
658
  } else { //show login screen
659
  $this->mo_2_factor_pass2login_show_wp_login_form();
 
 
 
660
  }
661
  }
662
 
@@ -768,12 +905,12 @@ class Miniorange_Password_2Factor_Login {
768
  wp_enqueue_script( 'miniorange_script', plugins_url( 'includes/js/rba/js/miniorange-fp.js', dirname(dirname(__FILE__)) ) );
769
  }else{
770
 
771
-
772
- if( get_option('mo2f_enable_2fa_prompt_on_login_page') &&
773
- in_array(get_option('mo2f_configured_2_factor_method'), array("Google Authenticator", "miniOrange Soft Token", "Authy Authenticator"))){
774
  echo "\t<p>\n";
775
  echo "\t\t<label class=\"mo2f_instuction1\" title=\"".__('If you don\'t have 2-factor authentication enabled for your WordPress account, leave this field empty.','google-authenticator')."\">".__('2 Factor Authentication code*','google-authenticator')."<span id=\"google-auth-info\"></span><br />\n";
776
- echo "\t\t<input type=\"text\" name=\"mo_softtoken\" id=\"mo2f_2fa_code\" class=\"mo2f_2fa_code\" value=\"\" size=\"20\" style=\"ime-mode: inactive;\" /></label>\n";
777
  echo "\t<p class=\"mo2f_instuction2\" style='color:red; font-size:12px;padding:5px'>* Skip the authentication code if it doesn't apply.</p>\n";
778
  echo "\t</p>\n";
779
  echo " \r\n";
@@ -832,40 +969,46 @@ class Miniorange_Password_2Factor_Login {
832
  }
833
 
834
  function mo2f_pass2login_push_oobemail_verification( $current_user, $mo2f_second_factor, $redirect_to, $session_id=null ) {
835
-
836
- global $Mo2fdbQueries;
837
- if(is_null($session_id)){
838
- $session_id=$this->create_session();
839
- }
840
- $user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $current_user->ID );
841
- $challengeMobile = new Customer_Setup();
842
- $content = $challengeMobile->send_otp_token( $user_email, $mo2f_second_factor, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) );
843
- $response = json_decode( $content, true );
844
-
845
- if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate Qr code */
846
- if ( $response['status'] == 'SUCCESS' ) {
847
- MO2f_Utility::set_user_values( $session_id, "mo2f_transactionId", $response['txId'] );
848
- $this->mo2f_transactionid=$response['txId'];
849
-
850
- $mo2fa_login_message = $mo2f_second_factor == 'PUSH NOTIFICATIONS' ? 'A Push Notification has been sent to your phone. We are waiting for your approval.' : 'An email has been sent to ' . MO2f_Utility::mo2f_get_hidden_email( $user_email ) . '. We are waiting for your approval.';
851
- $mo2fa_login_status = $mo2f_second_factor == 'PUSH NOTIFICATIONS' ? 'MO_2_FACTOR_CHALLENGE_PUSH_NOTIFICATIONS' : 'MO_2_FACTOR_CHALLENGE_OOB_EMAIL';
852
- $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to,null,$session_id);
853
- } else if ( $response['status'] == 'ERROR' || $response['status'] == 'FAILED' ) {
854
- MO2f_Utility::set_user_values( $session_id, "mo2f_transactionId", $response['txId'] );
855
- $this->mo2f_transactionid=$response['txId'];
856
- $mo2fa_login_message = $mo2f_second_factor == 'PUSH NOTIFICATIONS' ? 'An error occured while sending push notification to your app. You can click on <b>Phone is Offline</b> button to enter soft token from app or <b>Forgot your phone</b> button to receive OTP to your registered email.' : 'An error occured while sending email. Please try again.';
857
- $mo2fa_login_status = $mo2f_second_factor == 'PUSH NOTIFICATIONS' ? 'MO_2_FACTOR_CHALLENGE_PUSH_NOTIFICATIONS' : 'MO_2_FACTOR_CHALLENGE_OOB_EMAIL';
858
- $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to, null,$session_id );
859
- }
860
- } else {
861
- $this->remove_current_activity($session_id);
862
- $error = new WP_Error();
863
- $error->add( 'empty_username', __( '<strong>ERROR</strong>: An error occured while processing your request. Please Try again.' ) );
864
-
865
- return $error;
 
866
  }
 
 
 
 
867
 
868
-
 
869
  }
870
 
871
  function mo2f_pass2login_otp_verification( $user, $mo2f_second_factor, $redirect_to,$session_id=null ) {
@@ -959,6 +1102,10 @@ class Miniorange_Password_2Factor_Login {
959
 
960
  $is_customer_admin = get_option( 'mo2f_miniorange_admin' ) == $currentuser->ID ? true : false;
961
 
 
 
 
 
962
  if ( $is_customer_admin ) {
963
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $currentuser->ID );
964
  $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $currentuser->ID );
@@ -970,7 +1117,13 @@ class Miniorange_Password_2Factor_Login {
970
  $mo2f_allwed_login_attempts= 'disabled';
971
  }
972
  update_user_meta( $currentuser->ID, 'mo2f_user_login_attempts', $mo2f_allwed_login_attempts );
973
- if ( $email && $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) { //checking if user has configured any 2nd factor method
 
 
 
 
 
 
974
  try {
975
  $mo2f_rba_status = mo2f_collect_attributes( $email, stripslashes( $attributes ) ); // Rba flow
976
  MO2f_Utility::set_user_values( $session_id_encrypt, 'mo2f_rba_status', $mo2f_rba_status );
@@ -990,17 +1143,44 @@ class Miniorange_Password_2Factor_Login {
990
  exit;
991
  } else {
992
  $mo2f_second_factor = '';
993
-
994
- $mo2f_second_factor = mo2f_get_user_2ndfactor( $currentuser );
995
- if(get_option('mo2f_enable_2fa_prompt_on_login_page')&& !get_option('mo2f_remember_device') && in_array(get_option('mo2f_configured_2_factor_method'), array("Google Authenticator", "miniOrange Soft Token", "Authy Authenticator")) && !isset($_POST['mo_woocommerce_login_prompt'])){
996
- $error=$this->mo2f_validate_soft_token($currentuser, $redirect_to, $mo2f_second_factor, $otp_token,$session_id_encrypt);
997
-
998
- if(is_wp_error( $error)){
999
- return $error;
 
 
 
 
 
 
 
 
 
1000
  }
1001
-
1002
-
1003
- }else{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1004
  if ( MO2f_Utility::check_if_request_is_from_mobile_device( $_SERVER['HTTP_USER_AGENT'] ) && $kba_configuration_status ) {
1005
  $this->mo2f_pass2login_kba_verification( $currentuser->ID, $redirect_to, $session_id_encrypt );
1006
  } else {
@@ -1008,7 +1188,11 @@ class Miniorange_Password_2Factor_Login {
1008
  $this->mo2f_pass2login_mobile_verification( $currentuser, $redirect_to, $session_id_encrypt );
1009
  } else if ( $mo2f_second_factor == 'PUSH NOTIFICATIONS' || $mo2f_second_factor == 'OUT OF BAND EMAIL' ) {
1010
  $this->mo2f_pass2login_push_oobemail_verification( $currentuser, $mo2f_second_factor, $redirect_to, $session_id_encrypt );
1011
- } else if ( $mo2f_second_factor == 'SOFT TOKEN' || $mo2f_second_factor == 'SMS' || $mo2f_second_factor == 'PHONE VERIFICATION' || $mo2f_second_factor == 'GOOGLE AUTHENTICATOR' ) {
 
 
 
 
1012
  $this->mo2f_pass2login_otp_verification( $currentuser, $mo2f_second_factor, $redirect_to, $session_id_encrypt );
1013
  } else if ( $mo2f_second_factor == 'KBA' ) {
1014
  $this->mo2f_pass2login_kba_verification( $currentuser->ID, $redirect_to , $session_id_encrypt );
@@ -1018,7 +1202,6 @@ class Miniorange_Password_2Factor_Login {
1018
  $this->remove_current_activity($session_id_encrypt);
1019
  $error = new WP_Error();
1020
  $error->add( 'empty_username', __( '<strong>ERROR</strong>: Two Factor method has not been configured.' ) );
1021
-
1022
  return $error;
1023
  }
1024
  }
@@ -1026,6 +1209,7 @@ class Miniorange_Password_2Factor_Login {
1026
 
1027
  }
1028
  } else {
 
1029
  return $currentuser;
1030
  }
1031
 
@@ -1039,7 +1223,6 @@ class Miniorange_Password_2Factor_Login {
1039
  function mo2f_validate_soft_token($currentuser, $redirect_to = null, $mo2f_second_factor, $softtoken,$session_id_encrypt){
1040
  global $Mo2fdbQueries;
1041
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $currentuser->ID );
1042
-
1043
  $customer = new Customer_Setup();
1044
  $content = json_decode( $customer->validate_otp_token( $mo2f_second_factor, $email, null, $softtoken, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1045
 
@@ -1103,40 +1286,88 @@ class Miniorange_Password_2Factor_Login {
1103
  return $currentuser;
1104
  } else {
1105
  global $Mo2fdbQueries;
 
 
 
1106
  $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $currentuser->ID );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1107
 
1108
- if ( empty( $_POST['mo_softtoken'] ) && get_option('mo2f_enable_2fa_prompt_on_login_page') && $mo2f_configured_2FA_method && !get_option('mo2f_remember_device')&&
1109
- in_array(get_option('mo2f_configured_2_factor_method'), array("Google Authenticator", "miniOrange Soft Token", "Authy Authenticator"))) { // Prevent PHP notices when using app password login
1110
- if(isset($_POST['mo_woocommerce_login_prompt'])){
1111
 
1112
- $this->miniorange_initiate_2nd_factor( $currentuser, "", "","");
1113
- }
1114
- return new WP_Error( 'one_time_passcode_empty', '<strong>ERROR</strong>: Please enter the One Time Passcode.');
1115
- } else {
1116
- $otp_token = isset($_POST[ 'mo_softtoken' ]) ? trim( $_POST[ 'mo_softtoken' ] ) : '';
1117
- }
 
 
 
 
 
 
1118
 
1119
- $attributes = isset( $_POST['miniorange_rba_attribures'] ) ? $_POST['miniorange_rba_attribures'] : null;
1120
 
1121
- $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;
 
 
1122
 
1123
- $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
1124
- if(is_null($session_id)) {
1125
- $session_id=$this->create_session();
1126
- }
1127
 
1128
- $key = get_option('mo2f_customer_token');
1129
-
1130
- $error=$this->miniorange_initiate_2nd_factor( $currentuser, $attributes, $redirect_to, $otp_token, $session_id );
1131
 
1132
 
1133
- if(is_wp_error( $error)){
1134
- return $error;
1135
- }
1136
- return $error;
1137
-
 
1138
  }
1139
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1140
  }
1141
 
1142
  function mo_2_factor_enable_jquery_default_login() {
@@ -1164,6 +1395,7 @@ class Miniorange_Password_2Factor_Login {
1164
 
1165
  }
1166
 
 
1167
  }
1168
 
1169
  ?>
1
+ <?php
2
  /** miniOrange enables user to log in through mobile authentication as an additional layer of security over password.
3
  * Copyright (C) 2015 miniOrange
4
  *
22
  * Contains Request Calls to Customer service.
23
  **/
24
 
25
+ include 'two_fa_login.php';
26
  class Miniorange_Password_2Factor_Login {
27
 
28
  private $mo2f_kbaquestions;
29
  private $mo2f_userID;
30
  private $mo2f_rbastatus;
31
  private $mo2f_transactionid;
32
+
33
+
34
  public function miniorange_pass2login_redirect() {
35
  do_action('mo2f_network_init');
36
  global $Mo2fdbQueries;
51
  $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
52
  return $error;
53
  } else {
 
54
  $this->miniorange_pass2login_start_session();
55
  $mobile_login = new Miniorange_Mobile_Login();
56
  //validation and sanitization
62
  } else {
63
  $username = sanitize_text_field( $_POST['mo2fa_username'] );
64
  }
65
+ if ( username_exists( $username ) ) { /*if username exists in wp site */
 
66
  $user = new WP_User( $username );
67
  $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;
68
  MO2f_Utility::set_user_values($session_id, 'mo2f_current_user_id', $user->ID );
74
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
75
  $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID );
76
  $kba_configuration_status = $Mo2fdbQueries->get_user_detail( 'mo2f_SecurityQuestions_config_status', $user->ID );
77
+
78
+ if(MO2F_IS_ONPREM and !empty(get_user_meta($user->ID,'currentMethod',true)))
79
+ {
80
+ $configuredMethod = get_user_meta($user->ID,'currentMethod',true);
81
+ $mo2f_configured_2FA_method = empty($configuredMethod) ? 0 : 1;
82
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_PLUGIN_SETTINGS';
83
+ $email = get_user_meta($user->ID , 'email',true);
84
+
85
+ }
86
  if ( $mo2f_configured_2FA_method ) {
87
+ if ( $email && $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' or (MO2F_IS_ONPREM and $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS')) {
88
  if ( MO2f_Utility::check_if_request_is_from_mobile_device( $_SERVER['HTTP_USER_AGENT'] ) && $kba_configuration_status ) {
89
  $this->mo2f_pass2login_kba_verification( $user->ID, $redirect_to, $session_id );
90
  } else {
91
+ $mo2f_second_factor = '';
92
  $mo2f_second_factor = mo2f_get_user_2ndfactor( $user );
93
+ if(MO2F_IS_ONPREM)
94
+ {
95
+ //$user = get_userdatabylogin('admin');
96
+ $mo2f_second_factor = get_user_meta($user->ID,'currentMethod',true);
97
+
98
+ if($mo2f_second_factor == 'Security Questions')
99
+ {
100
+ $mo2f_second_factor = 'KBA';
101
+ }
102
+ else if($mo2f_second_factor == 'Google Authenticator')
103
+ {
104
+ $mo2f_second_factor = 'GOOGLE AUTHENTICATOR';
105
+ }
106
+ else if($mo2f_second_factor != 'Email Verification')
107
+ $mo2f_second_factor = 'NONE';
108
+ }
109
+
110
  if ( $mo2f_second_factor == 'MOBILE AUTHENTICATION' ) {
111
  $this->mo2f_pass2login_mobile_verification( $user, $redirect_to, $session_id );
112
  } else if ( $mo2f_second_factor == 'PUSH NOTIFICATIONS' || $mo2f_second_factor == 'OUT OF BAND EMAIL' ) {
113
  $this->mo2f_pass2login_push_oobemail_verification( $user, $mo2f_second_factor, $redirect_to, $session_id );
114
+ }
115
+ else if($mo2f_second_factor == 'Email Verification'){
116
+ $this->mo2f_pass2login_push_oobemail_verification( $user, $mo2f_second_factor, $redirect_to, $session_id );
117
+ }
118
+ else if ( $mo2f_second_factor == 'SOFT TOKEN' || $mo2f_second_factor == 'SMS' || $mo2f_second_factor == 'PHONE VERIFICATION' || $mo2f_second_factor == 'GOOGLE AUTHENTICATOR' ) {
119
  $this->mo2f_pass2login_otp_verification( $user, $mo2f_second_factor, $redirect_to, $session_id );
120
  } else if ( $mo2f_second_factor == 'KBA' ) {
121
  $this->mo2f_pass2login_kba_verification( $user->ID, $redirect_to, $session_id );
127
  }
128
  } else {
129
  MO2f_Utility::set_user_values($session_id, 'mo2f_login_message', 'Please login into your account using password.' );
130
+ $mobile_login->mo_auth_show_success_message('Please login into your account using password.');
131
+ update_user_meta($user->ID,'userMessage','Please login into your account using password.');
132
  $mobile_login->mo2f_redirectto_wp_login();
133
  }
134
+ } else {
135
  MO2f_Utility::set_user_values( $session_id, "mo2f_login_message", 'Please login into your account using password.' );
136
+ $mobile_login->mo_auth_show_success_message('Please login into your account using password.');
137
+ update_user_meta($user->ID,'userMessage','Please login into your account using password.');
138
  $mobile_login->mo2f_redirectto_wp_login();
 
139
  }
140
  } else {
141
  $mobile_login->remove_current_activity($session_id);
142
  MO2f_Utility::set_user_values( $session_id, "mo2f_login_message", 'Invalid Username.' );
143
+ $mobile_login->mo_auth_show_error_message('Invalid Username.');
144
  }
145
  }
146
  }
147
 
148
  }
149
+ if(isset($_GET['Txid'])&&isset($_GET['accessToken']))
150
+ {
151
+ $userIDGet = sanitize_text_field($_GET['userID']);
152
+ $txIdGet = sanitize_text_field($_GET['Txid']);
153
+ $otpToken = get_site_option($userIDGet);
154
+ $txidstatus = get_site_option($txIdGet);
155
+ $userIDd = $userIDGet.'D';
156
+ $otpTokenD = get_site_option($userIDd);
157
+ $mo2f_dirName = dirname(__FILE__);
158
+ $mo2f_dirName = explode('wp-content', $mo2f_dirName);
159
+ $mo2f_dirName = explode('handler', $mo2f_dirName[1]);
160
+
161
+ $head = "You are not authorized to perform this action";
162
+ $body = "Please contact to your admin";
163
+ $color = "red";
164
+ if(3 == $txidstatus)
165
+ {
166
+ $time = "time".$txIdGet;
167
+ $currentTimeInMillis = round(microtime(true) * 1000);
168
+ $generatedTimeINMillis = get_site_option($time);
169
+ $difference = ($currentTimeInMillis-$generatedTimeINMillis)/1000 ;
170
+ if($difference <= 300)
171
+ {
172
+ $accessTokenGet = sanitize_text_field($_GET['accessToken']);
173
+ if( $accessTokenGet == $otpToken)
174
+ {
175
+ update_site_option($txIdGet,1);
176
+ $body = "Transaction has been successfully validated.<br><br>Please continue with the transaction.";
177
+ $head = "TRANSACTION SUCCESSFUL";
178
+ $color = "green";
179
+ }
180
+ else if($accessTokenGet==$otpTokenD)
181
+ {
182
+ update_site_option($txIdGet,0);
183
+ $body = "Transaction has been Canceled.<br><br>Please Try Again.";
184
+ $head = "TRANSACTION DENIED";
185
+ }
186
+ }
187
+ delete_site_option($userIDGet);
188
+ delete_site_option($userIDd);
189
+ delete_site_option($time);
190
+
191
+ }
192
+
193
+ $this->display_email_verification($head,$body,$color);
194
+ exit;
195
+
196
+ }
197
+ else if(isset($_POST['txid']))
198
+ {
199
+ $txidpost = sanitize_text_field($_POST['txid']);
200
+ $status = get_site_option($txidpost);
201
+ update_option('optionVal1',$status); //??
202
+ if($status ==1 || $status ==0)
203
+ delete_site_option($txidpost);
204
+ echo $status;
205
+ exit();
206
+ }
207
+
208
+ else if ( isset( $_POST['mo2f_trust_device_confirm_nonce'] ) ) { /*register device as rba profile */
209
  $nonce = $_POST['mo2f_trust_device_confirm_nonce'];
210
  if ( ! wp_verify_nonce( $nonce, 'miniorange-2-factor-trust-device-confirm-nonce' ) ) {
211
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
298
  $this->mo2f_pass2login_kba_verification( $user_id, $redirect_to,$session_id_encrypt );
299
  }
300
  }else if ( isset( $_POST['miniorange_kba_nonce'] ) ) { /*check kba validation*/
 
301
  $nonce = $_POST['miniorange_kba_nonce'];
302
  if ( ! wp_verify_nonce( $nonce, 'miniorange-2-factor-kba-nonce' ) ) {
303
  $error = new WP_Error();
304
  $error->add( 'empty_username', __( '<strong>ERROR</strong>: Invalid Request.' ) );
305
  return $error;
306
+ }
307
+ else{
308
+
309
  $this->miniorange_pass2login_start_session();
310
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
311
  $user_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_current_user_id',$session_id_encrypt );
318
  }
319
  $otpToken = array();
320
  $kba_questions = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo_2_factor_kba_questions',$session_id_encrypt );
321
+
322
  $otpToken[0] = $kba_questions[0];
323
  $otpToken[1] = sanitize_text_field( $_POST['mo2f_answer_1'] );
324
  $otpToken[2] = $kba_questions[1];
325
  $otpToken[3] = sanitize_text_field( $_POST['mo2f_answer_2'] );
326
  $check_trust_device = isset( $_POST['mo2f_trust_device'] ) ? $_POST['mo2f_trust_device'] : 'false';
 
327
  //if the php session folder has insufficient permissions, cookies to be used
328
  $mo2f_login_transaction_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_transactionId', $session_id_encrypt );
329
 
352
  $this->remove_current_activity($session_id_encrypt);
353
  return new WP_Error( 'invalid_username', __( '<strong>ERROR</strong>: Please try again..' ) );
354
  }
355
+
356
+ }
357
+ }else if ( isset( $_POST['miniorange_mobile_validation_nonce'] ) ) {
358
+ /*check mobile validation */
359
  $nonce = $_POST['miniorange_mobile_validation_nonce'];
360
  if ( ! wp_verify_nonce( $nonce, 'miniorange-2-factor-mobile-validation-nonce' ) ) {
361
  $error = new WP_Error();
362
  $error->add( 'empty_username', __( '<strong>ERROR</strong>: Invalid Request.' ) );
363
  return $error;
364
  } else {
365
+ if(MO2F_IS_ONPREM )
366
+ {
367
+ $txid = $_POST['TxidEmail'];
368
+ $status = get_option($txid);
369
+ if($status != '')
370
+ {
371
+ if($status != 1)
372
+ {
373
+ return new WP_Error( 'invalid_username', __( '<strong>ERROR</strong>: Please try again.' ) );
374
+ }
375
+ }
376
+ }
377
  $this->miniorange_pass2login_start_session();
378
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
379
  //if the php session folder has insufficient permissions, cookies to be used
382
  $checkMobileStatus = new Two_Factor_Setup();
383
  $content = $checkMobileStatus->check_mobile_status( $mo2f_login_transaction_id );
384
  $response = json_decode( $content, true );
385
+ if(MO2F_IS_ONPREM)
386
+ {
387
+ $this->mo2fa_pass2login($redirect_to,$session_id_encrypt);
388
+ }
389
  if ( json_last_error() == JSON_ERROR_NONE ) {
390
  if ( $response['status'] == 'SUCCESS' ) {
391
  if ( get_option( 'mo2f_remember_device' ) ) {
413
  $this->miniorange_pass2login_start_session();
414
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
415
  $this->remove_current_activity($session_id_encrypt);
416
+
417
  }
418
  }else if ( isset( $_POST['miniorange_forgotphone'] ) ) { /*Click on the link of forgotphone */
419
  $nonce = $_POST['miniorange_forgotphone'];
491
  $redirect_to = isset( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : null;
492
  $softtoken = '';
493
  $user_id = MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_current_user_id',$session_id_encrypt );
494
+
495
+ $attempts = get_option('mo2f_attempts_before_redirect', 3);
496
  if ( MO2f_utility::mo2f_check_empty_or_null( $_POST['mo2fa_softtoken'] ) ) {
497
  if($attempts>1 || $attempts=='disabled')
498
  {
499
+ update_option('mo2f_attempts_before_redirect', $attempts-1 );
500
+ $mo2fa_login_message = 'Please enter OTP to proceed.';
501
+ $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to,null,$session_id_encrypt );
 
 
502
  }else{
503
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
504
  $this->remove_current_activity($session_id_encrypt);
510
  if ( ! MO2f_utility::mo2f_check_number_length( $softtoken ) ) {
511
  if($attempts>1|| $attempts=='disabled')
512
  {
513
+ update_option('mo2f_attempts_before_redirect', $attempts-1 );
 
 
514
  $mo2fa_login_message = 'Invalid OTP. Only digits within range 4-8 are allowed. Please try again.';
515
  $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to,null,$session_id_encrypt );
516
 
517
  }else{
518
+ $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
519
+ $this->remove_current_activity($session_id_encrypt);
520
+ update_option('mo2f_attempts_before_redirect', 3);
521
+ return new WP_Error( 'limit_exceeded', '<strong>ERROR</strong>: Number of attempts exceeded.');
522
  }
523
  }
524
  }
541
  $content = json_decode( $customer->validate_otp_token( 'SOFT TOKEN', $user_email, null, $softtoken, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
542
  } else if ( isset( $mo2fa_login_status ) && $mo2fa_login_status == 'MO_2_FACTOR_CHALLENGE_GOOGLE_AUTHENTICATION' ) {
543
 
544
+ $content = json_decode( $customer->validate_otp_token( 'GOOGLE AUTHENTICATOR', $user_email, null, $softtoken, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
545
 
546
  } else {
547
  $this->remove_current_activity($session_id_encrypt);
549
  }
550
 
551
  if ( strcasecmp( $content['status'], 'SUCCESS' ) == 0 ) {
552
+ update_option('mo2f_attempts_before_redirect', 3);
553
  if ( get_option( 'mo2f_remember_device' ) ) {
554
  $mo2fa_login_status = 'MO_2_FACTOR_REMEMBER_TRUSTED_DEVICE';
555
  $this->miniorange_pass2login_form_fields( $mo2fa_login_status, null, $redirect_to,null,$session_id_encrypt );
559
  } else {
560
  if($attempts>1 || $attempts=='disabled')
561
  {
562
+ update_option('mo2f_attempts_before_redirect', $attempts-1);
 
 
563
  $message = $mo2fa_login_status == 'MO_2_FACTOR_CHALLENGE_SOFT_TOKEN' ? 'You have entered an invalid OTP.<br>Please click on <b>Sync Time</b> in the miniOrange Authenticator app to sync your phone time with the miniOrange servers and try again.' : 'Invalid OTP. Please try again.';
564
  $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $message, $redirect_to,null,$session_id_encrypt );
565
  }else{
566
  $session_id_encrypt = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
567
  $this->remove_current_activity($session_id_encrypt);
568
+ update_option('mo2f_attempts_before_redirect', 3);
569
  return new WP_Error( 'limit_exceeded', '<strong>ERROR</strong>: Number of attempts exceeded.');
570
  }
571
  }
604
 
605
  $attributes = isset( $_POST['miniorange_rba_attribures'] ) ? $_POST['miniorange_rba_attribures'] : null;
606
  $redirect_to = isset( $_POST['redirect_to'] ) ? $_POST['redirect_to'] : null;
607
+ $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
608
  $this->miniorange_initiate_2nd_factor( $currentuser, $attributes, $redirect_to,$session_id );
609
  }
610
  }
611
  }
612
 
613
+ function deniedMessage($message)
614
+ {
615
+ if(empty($message) && get_option("deniedMessage") )
616
+ {
617
+ delete_option('deniedMessage');
618
+ //return "<strong style='color: red'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You have denied the request</strong>";
619
+ }
620
+ else
621
+ return $message;
622
+ }
623
  function remove_current_activity($session_id) {
624
  global $Mo2fdbQueries;
625
  $session_variables = array(
692
  }
693
 
694
  function mo2f_pass2login_kba_verification( $user_id, $redirect_to, $session_id ) {
695
+ global $Mo2fdbQueries,$LoginuserID;
696
+ $LoginuserID = $user_id;
697
  $user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user_id );
698
+ if(is_null($session_id)) {
 
699
  $session_id=$this->create_session();
700
  }
701
+ if(MO2F_IS_ONPREM){
702
+ $question_answers = get_user_meta($user_id , 'mo2f_kba_challenge', true);
703
+ $challenge_questions = array_keys($question_answers);
704
+ $random_keys = array_rand($challenge_questions,2);
705
+ $challenge_ques1 = $challenge_questions[$random_keys[0]];
706
+ $challenge_ques2 = $challenge_questions[$random_keys[1]];
707
+ $questions = array($challenge_ques1,$challenge_ques2);
708
+ update_user_meta( $user_id, 'kba_questions_user', $questions );
709
+ $mo2fa_login_message = 'Please answer the following questions:';
710
+ $mo2fa_login_status = 'MO_2_FACTOR_CHALLENGE_KBA_AUTHENTICATION';
711
+ $mo2f_kbaquestions = $questions;
712
+ MO2f_Utility::set_user_values( $session_id, 'mo_2_factor_kba_questions', $questions );
713
+ $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to,null, $session_id ,$this->mo2f_kbaquestions );
714
+ }
715
 
716
+ else{
717
  $challengeKba = new Customer_Setup();
718
  $content = $challengeKba->send_otp_token( $user_email, 'KBA', get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) );
719
  $response = json_decode( $content, true );
743
 
744
  return $error;
745
  }
746
+ }
747
  }
748
 
749
  function miniorange_pass2login_form_fields( $mo2fa_login_status = null, $mo2fa_login_message = null, $redirect_to = null, $qrCode = null, $session_id_encrypt ) {
777
  exit;
778
  } else if ( $this->miniorange_pass2login_check_kba_status( $login_status ) ) { // for Kba
779
  $kbaquestions = $this->mo2f_kbaquestions ? $this->mo2f_kbaquestions : MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo_2_factor_kba_questions',$session_id_encrypt );
780
+ if(MO2F_IS_ONPREM){
781
+ $user_id = $this->mo2f_userID ? $this->mo2f_userID : MO2f_Utility::mo2f_retrieve_user_temp_values( 'mo2f_current_user_id',$session_id_encrypt );
782
+ $ques = get_user_meta( $user_id, 'kba_questions_user');
783
+ mo2f_get_kba_authentication_prompt( $login_message, $redirect_to, $session_id_encrypt, $ques[0] );
784
+ }
785
+ else{
786
  mo2f_get_kba_authentication_prompt( $login_message, $redirect_to, $session_id_encrypt, $kbaquestions );
787
+ }
788
  exit;
789
  } else if ( $this->miniorange_pass2login_check_trusted_device_status( $login_status ) ) { // trusted device
790
  mo2f_get_device_form( $redirect_to, $session_id_encrypt );
791
  exit;
792
  } else { //show login screen
793
  $this->mo_2_factor_pass2login_show_wp_login_form();
794
+ if(MO2F_IS_ONPREM){
795
+ $this->mo_2_factor_pass2login_show_wp_login_form();
796
+ }
797
  }
798
  }
799
 
905
  wp_enqueue_script( 'miniorange_script', plugins_url( 'includes/js/rba/js/miniorange-fp.js', dirname(dirname(__FILE__)) ) );
906
  }else{
907
 
908
+
909
+ if( get_option('mo2f_enable_2fa_prompt_on_login_page'))
910
+ {
911
  echo "\t<p>\n";
912
  echo "\t\t<label class=\"mo2f_instuction1\" title=\"".__('If you don\'t have 2-factor authentication enabled for your WordPress account, leave this field empty.','google-authenticator')."\">".__('2 Factor Authentication code*','google-authenticator')."<span id=\"google-auth-info\"></span><br />\n";
913
+ echo "\t\t<input type=\"text\" placeholder=\"No soft Token ? Skip\" name=\"mo_softtoken\" id=\"mo2f_2fa_code\" class=\"mo2f_2fa_code\" value=\"\" size=\"20\" style=\"ime-mode: inactive;\" /></label>\n";
914
  echo "\t<p class=\"mo2f_instuction2\" style='color:red; font-size:12px;padding:5px'>* Skip the authentication code if it doesn't apply.</p>\n";
915
  echo "\t</p>\n";
916
  echo " \r\n";
969
  }
970
 
971
  function mo2f_pass2login_push_oobemail_verification( $current_user, $mo2f_second_factor, $redirect_to, $session_id=null ) {
972
+
973
+ global $Mo2fdbQueries;
974
+ if(is_null($session_id)){
975
+ $session_id=$this->create_session();
976
+ }
977
+ $challengeMobile = new Customer_Setup();
978
+ if(MO2F_IS_ONPREM){
979
+ $user_email = get_user_meta($current_user->ID,'email',true);
980
+ include_once dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'api'.DIRECTORY_SEPARATOR.'Mo2f_OnPremRedirect.php';
981
+ $mo2fOnPremRedirect = new Mo2f_OnPremRedirect();
982
+ // $content = $mo2fOnPremRedirect->OnpremSendRedirect($uKey,$authType );//change parameters as per your requirement but make sure other methods are not affected.
983
+ $content = $mo2fOnPremRedirect->mo2f_pass2login_push_email_onpremise($current_user, $redirect_to, $session_id );
984
+
985
+ }else {
986
+ $user_email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $current_user->ID );
987
+ $content = $challengeMobile->send_otp_token( $user_email, $mo2f_second_factor, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) );
988
+ }
989
+ $response = json_decode( $content, true );
990
+ if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate Qr code */
991
+ if ( $response['status'] == 'SUCCESS' ) {
992
+ MO2f_Utility::set_user_values( $session_id, "mo2f_transactionId", $response['txId'] );
993
+ $this->mo2f_transactionid=$response['txId'];
994
+
995
+ $mo2fa_login_message = $mo2f_second_factor == 'PUSH NOTIFICATIONS' ? 'A Push Notification has been sent to your phone. We are waiting for your approval.' : 'An email has been sent to ' . MO2f_Utility::mo2f_get_hidden_email( $user_email ) . '. We are waiting for your approval.';
996
+ $mo2fa_login_status = $mo2f_second_factor == 'PUSH NOTIFICATIONS' ? 'MO_2_FACTOR_CHALLENGE_PUSH_NOTIFICATIONS' : 'MO_2_FACTOR_CHALLENGE_OOB_EMAIL';
997
+ $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to,null,$session_id);
998
+ } else if ( $response['status'] == 'ERROR' || $response['status'] == 'FAILED' ) {
999
+ MO2f_Utility::set_user_values( $session_id, "mo2f_transactionId", $response['txId'] );
1000
+ $this->mo2f_transactionid=$response['txId'];
1001
+ $mo2fa_login_message = $mo2f_second_factor == 'PUSH NOTIFICATIONS' ? 'An error occured while sending push notification to your app. You can click on <b>Phone is Offline</b> button to enter soft token from app or <b>Forgot your phone</b> button to receive OTP to your registered email.' : 'An error occured while sending email. Please try again.';
1002
+ $mo2fa_login_status = $mo2f_second_factor == 'PUSH NOTIFICATIONS' ? 'MO_2_FACTOR_CHALLENGE_PUSH_NOTIFICATIONS' : 'MO_2_FACTOR_CHALLENGE_OOB_EMAIL';
1003
+ $this->miniorange_pass2login_form_fields( $mo2fa_login_status, $mo2fa_login_message, $redirect_to, null,$session_id );
1004
  }
1005
+ } else {
1006
+ $this->remove_current_activity($session_id);
1007
+ $error = new WP_Error();
1008
+ $error->add( 'empty_username', __( '<strong>ERROR</strong>: An error occured while processing your request. Please Try again.' ) );
1009
 
1010
+ return $error;
1011
+ }
1012
  }
1013
 
1014
  function mo2f_pass2login_otp_verification( $user, $mo2f_second_factor, $redirect_to,$session_id=null ) {
1102
 
1103
  $is_customer_admin = get_option( 'mo2f_miniorange_admin' ) == $currentuser->ID ? true : false;
1104
 
1105
+ if(MO2F_IS_ONPREM)
1106
+ {
1107
+ $is_customer_admin = true;
1108
+ }
1109
  if ( $is_customer_admin ) {
1110
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $currentuser->ID );
1111
  $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $currentuser->ID );
1117
  $mo2f_allwed_login_attempts= 'disabled';
1118
  }
1119
  update_user_meta( $currentuser->ID, 'mo2f_user_login_attempts', $mo2f_allwed_login_attempts );
1120
+
1121
+ if(MO2F_IS_ONPREM)
1122
+ {
1123
+ $mo_2factor_user_registration_status = 'MO_2_FACTOR_PLUGIN_SETTINGS';
1124
+ $email = get_user_meta($currentuser->ID , 'email',true);
1125
+ }
1126
+ if ( ($email && $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS') or (MO2F_IS_ONPREM and $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS')) { //checking if user has configured any 2nd factor method
1127
  try {
1128
  $mo2f_rba_status = mo2f_collect_attributes( $email, stripslashes( $attributes ) ); // Rba flow
1129
  MO2f_Utility::set_user_values( $session_id_encrypt, 'mo2f_rba_status', $mo2f_rba_status );
1143
  exit;
1144
  } else {
1145
  $mo2f_second_factor = '';
1146
+ $mo2f_second_factor = mo2f_get_user_2ndfactor( $currentuser );
1147
+ if(MO2F_IS_ONPREM)
1148
+ {
1149
+ $user = $currentuser;
1150
+ $roles = ( array ) $user->roles;
1151
+ $flag = 0;
1152
+ foreach ( $roles as $role ) {
1153
+ if(get_option('mo2fa_'.$role)=='1')
1154
+ $flag=1;
1155
+ }
1156
+ //$user = get_userdatabylogin('admin');
1157
+ $mo2f_second_factor = get_user_meta($currentuser->ID,'currentMethod',true);
1158
+
1159
+ if($mo2f_second_factor == 'Security Questions')
1160
+ {
1161
+ $mo2f_second_factor = 'KBA';
1162
  }
1163
+ else if($mo2f_second_factor == 'Google Authenticator')
1164
+ {
1165
+ $mo2f_second_factor = 'GOOGLE AUTHENTICATOR';
1166
+ }
1167
+ else if($mo2f_second_factor != 'Email Verification')
1168
+ {
1169
+ $mo2f_second_factor = 'NONE';
1170
+ }
1171
+ if($flag == 0){
1172
+ $mo2f_second_factor = 'NONE';
1173
+ }
1174
+ }
1175
+ if((($mo2f_second_factor == 'GOOGLE AUTHENTICATOR') || ($mo2f_second_factor =='SOFT TOKEN') || ($mo2f_second_factor =='AUTHY AUTHENTICATOR')) && get_option('mo2f_enable_2fa_prompt_on_login_page')&& !get_option('mo2f_remember_device'))
1176
+ {
1177
+ $error=$this->mo2f_validate_soft_token($currentuser, $redirect_to, $mo2f_second_factor, $otp_token,$session_id_encrypt);
1178
+ if(is_wp_error( $error))
1179
+ {
1180
+ return $error;
1181
+ }
1182
+ }
1183
+ else{
1184
  if ( MO2f_Utility::check_if_request_is_from_mobile_device( $_SERVER['HTTP_USER_AGENT'] ) && $kba_configuration_status ) {
1185
  $this->mo2f_pass2login_kba_verification( $currentuser->ID, $redirect_to, $session_id_encrypt );
1186
  } else {
1188
  $this->mo2f_pass2login_mobile_verification( $currentuser, $redirect_to, $session_id_encrypt );
1189
  } else if ( $mo2f_second_factor == 'PUSH NOTIFICATIONS' || $mo2f_second_factor == 'OUT OF BAND EMAIL' ) {
1190
  $this->mo2f_pass2login_push_oobemail_verification( $currentuser, $mo2f_second_factor, $redirect_to, $session_id_encrypt );
1191
+ }
1192
+ else if($mo2f_second_factor == 'Email Verification'){
1193
+ $this->mo2f_pass2login_push_oobemail_verification( $currentuser, $mo2f_second_factor, $redirect_to, $session_id_encrypt );
1194
+ }
1195
+ else if ( $mo2f_second_factor == 'SOFT TOKEN' || $mo2f_second_factor == 'SMS' || $mo2f_second_factor == 'PHONE VERIFICATION' || $mo2f_second_factor == 'GOOGLE AUTHENTICATOR' ) {
1196
  $this->mo2f_pass2login_otp_verification( $currentuser, $mo2f_second_factor, $redirect_to, $session_id_encrypt );
1197
  } else if ( $mo2f_second_factor == 'KBA' ) {
1198
  $this->mo2f_pass2login_kba_verification( $currentuser->ID, $redirect_to , $session_id_encrypt );
1202
  $this->remove_current_activity($session_id_encrypt);
1203
  $error = new WP_Error();
1204
  $error->add( 'empty_username', __( '<strong>ERROR</strong>: Two Factor method has not been configured.' ) );
 
1205
  return $error;
1206
  }
1207
  }
1209
 
1210
  }
1211
  } else {
1212
+ //$this->mo2fa_pass2login( $redirect_to, $session_id_encrypt );
1213
  return $currentuser;
1214
  }
1215
 
1223
  function mo2f_validate_soft_token($currentuser, $redirect_to = null, $mo2f_second_factor, $softtoken,$session_id_encrypt){
1224
  global $Mo2fdbQueries;
1225
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $currentuser->ID );
 
1226
  $customer = new Customer_Setup();
1227
  $content = json_decode( $customer->validate_otp_token( $mo2f_second_factor, $email, null, $softtoken, get_option( 'mo2f_customerKey' ), get_option( 'mo2f_api_key' ) ), true );
1228
 
1286
  return $currentuser;
1287
  } else {
1288
  global $Mo2fdbQueries;
1289
+ $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
1290
+
1291
+ $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;
1292
  $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $currentuser->ID );
1293
+ if(MO2F_IS_ONPREM){
1294
+ $mo2f_configured_2FA_method = get_user_meta($currentuser->ID,'currentMethod',true);
1295
+ }
1296
+ if (MO2F_IS_ONPREM && $mo2f_configured_2FA_method=='Security Questions')
1297
+ {
1298
+ $this->miniorange_initiate_2nd_factor($currentuser, null , $redirect_to , "" , $session_id );
1299
+ }
1300
+ elseif(MO2F_IS_ONPREM && $mo2f_configured_2FA_method =='Email Verification')
1301
+ {
1302
+ $this->miniorange_initiate_2nd_factor($currentuser, null , $redirect_to , null ,$session_id );
1303
+ }
1304
+ else
1305
+ {
1306
+ if ( empty( $_POST['mo_softtoken'] ) && get_option('mo2f_enable_2fa_prompt_on_login_page') && $mo2f_configured_2FA_method && !get_option('mo2f_remember_device') && (($mo2f_configured_2FA_method == 'Google Authenticator') ||($mo2f_configured_2FA_method == 'miniOrange Soft Token') || ($mo2f_configured_2FA_method =='Authy Authenticator')))
1307
+ {
1308
+
1309
 
1310
+ if(isset($_POST['mo_woocommerce_login_prompt'])){
 
 
1311
 
1312
+ $this->miniorange_initiate_2nd_factor( $currentuser, "", "","");
1313
+ }
1314
+ return new WP_Error( 'one_time_passcode_empty', '<strong>ERROR</strong>: Please enter the One Time Passcode.');
1315
+ // Prevent PHP notices when using app password login
1316
+
1317
+ }
1318
+ else
1319
+ {
1320
+ $otp_token = isset($_POST[ 'mo_softtoken' ]) ? trim( $_POST[ 'mo_softtoken' ] ) : '';
1321
+ }
1322
+ $attributes = isset( $_POST['miniorange_rba_attribures'] ) ? $_POST['miniorange_rba_attribures'] : null;
1323
+ $session_id = isset( $_POST['session_id'] ) ? $_POST['session_id'] : null;
1324
 
1325
+ $redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : null;
1326
 
1327
+ if(is_null($session_id)) {
1328
+ $session_id=$this->create_session();
1329
+ }
1330
 
1331
+ // $key = get_option('mo2f_customer_token');
 
 
 
1332
 
1333
+ $error=$this->miniorange_initiate_2nd_factor( $currentuser, $attributes, $redirect_to, $otp_token, $session_id );
 
 
1334
 
1335
 
1336
+ if(is_wp_error( $error)){
1337
+ return $error;
1338
+ }
1339
+ return $error;
1340
+ }
1341
+ }
1342
  }
1343
+
1344
+ }
1345
+
1346
+ function display_email_verification($head,$body,$color)
1347
+ {
1348
+ echo "<div style='background-color: #d5e3d9; height:850px;' >
1349
+ <div style='height:350px; background-color: #3CB371; border-radius: 2px; padding:2%; '>
1350
+ <div class='mo2f_tamplate_layout' style='background-color: #ffffff;border-radius: 5px;box-shadow: 0 5px 15px rgba(0,0,0,.5); width:850px;height:350px; align-self: center; margin: 180px auto; ' >
1351
+ <img alt='logo' style='margin-left:240px ;
1352
+ margin-top:10px;width=40%;' src='https://auth.miniorange.com/moas/images/logo_large.png' />
1353
+ <div><hr></div>
1354
+
1355
+ <tbody>
1356
+ <tr>
1357
+ <td>
1358
+
1359
+ <p style='margin-top:0;margin-bottom:10px'>
1360
+ <p style='margin-top:0;margin-bottom:10px'> <h1 style='color:".$color.";text-align:center;font-size:50px'>".$head ."</h1></p>
1361
+ <p style='margin-top:0;margin-bottom:10px'>
1362
+ <p style='margin-top:0;margin-bottom:10px;text-align:center'><h2 style='text-align:center'>".$body."</h2></p>
1363
+ <p style='margin-top:0;margin-bottom:0px;font-size:11px'>
1364
+
1365
+ </td>
1366
+ </tr>
1367
+
1368
+ </div>
1369
+ </div>
1370
+ </div>";
1371
  }
1372
 
1373
  function mo_2_factor_enable_jquery_default_login() {
1395
 
1396
  }
1397
 
1398
+
1399
  }
1400
 
1401
  ?>
handler/twofa/two_fa_settings.php CHANGED
@@ -1,8 +1,9 @@
1
  <?php
2
 
3
- include dirname(__FILE__).DIRECTORY_SEPARATOR.'two_fa_pass2login.php';
4
  include dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_setup_notification.php';
5
  include 'class_miniorange_2fa_strong_password.php';
 
6
  class Miniorange_Authentication {
7
 
8
  private $defaultCustomerKey = "16555";
@@ -13,12 +14,13 @@ class Miniorange_Authentication {
13
  // add_action( 'admin_notices', array( $this, 'prompt_user_to_setup_two_factor' ) );
14
  add_action( 'admin_init', array( $this, 'miniorange_auth_save_settings' ) );
15
  add_action( 'plugins_loaded', array( $this, 'mo2f_update_db_check' ) );
 
16
  global $wp_roles;
17
  if ( ! isset( $wp_roles ) ) {
18
  $wp_roles = new WP_Roles();
19
  }
20
-
21
  if ( get_option( 'mo2f_activate_plugin' ) == 1 ) {
 
22
  $mo2f_rba_attributes = new Miniorange_Rba_Attributes();
23
  $pass2fa_login = new Miniorange_Password_2Factor_Login();
24
  $mo2f_2factor_setup = new Two_Factor_Setup();
@@ -45,12 +47,11 @@ class Miniorange_Authentication {
45
  'miniorange_pass2login_form_fields'
46
  ), 10, 5 );
47
  add_filter( 'mo2f_gauth_service', array( $mo2f_rba_attributes, 'mo2f_google_auth_service' ), 10, 1 );
48
-
49
-
50
  if ( get_option( 'mo2f_login_option' ) ) { //password + 2nd factor enabled
51
- if ( get_option( 'mo_2factor_admin_registration_status' ) == 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' ) {
52
 
53
  remove_filter( 'authenticate', 'wp_authenticate_username_password', 20 );
 
54
  add_filter( 'authenticate', array( $pass2fa_login, 'mo2f_check_username_password' ), 99999, 4 );
55
  add_action( 'init', array( $pass2fa_login, 'miniorange_pass2login_redirect' ) );
56
  add_action( 'login_form', array(
@@ -69,19 +70,11 @@ class Miniorange_Authentication {
69
  $pass2fa_login,
70
  'mo_2_factor_enable_jquery_default_login'
71
  ) );
72
-
73
- if(get_site_option('mo2f_woocommerce_login_prompt')){
74
- add_action( 'woocommerce_login_form', array(
75
  $pass2fa_login,
76
  'mo_2_factor_pass2login_show_wp_login_form'
77
  ) );
78
- }
79
- else if(!get_site_option('mo2f_woocommerce_login_prompt') && get_site_option('mo2f_enable_2fa_prompt_on_login_page') ) {
80
- add_action('woocommerce_login_form_end' ,array(
81
- $pass2fa_login,
82
- 'mo_2_factor_pass2login_woocommerce'
83
- ) );
84
- }
85
  add_action( 'wp_enqueue_scripts', array(
86
  $pass2fa_login,
87
  'mo_2_factor_enable_jquery_default_login'
@@ -105,10 +98,10 @@ class Miniorange_Authentication {
105
 
106
  } else { //login with phone enabled
107
 
108
- if ( get_option( 'mo_2factor_admin_registration_status' ) == 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' ) {
109
 
110
  $mobile_login = new Miniorange_Mobile_Login();
111
- add_action( 'login_form', array( $mobile_login, 'miniorange_login_form_fields' ), 10 );
112
  add_action( 'login_footer', array( $mobile_login, 'miniorange_login_footer_form' ) );
113
 
114
  remove_filter( 'authenticate', 'wp_authenticate_username_password', 20 );
@@ -125,6 +118,26 @@ class Miniorange_Authentication {
125
  }
126
 
127
  function mo2f_update_db_check() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  if(get_option('mo2f_network_features',"not_exits")=="not_exits"){
129
  do_action('mo2f_network_create_db');
130
  update_option('mo2f_network_features',1);
@@ -232,13 +245,16 @@ class Miniorange_Authentication {
232
  if ( $check_if_user_column_exists ) {
233
  $selected_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user_id );
234
 
235
- if ( in_array( $selected_2FA_method, array(
236
- "Google Authenticator",
237
- "miniOrange Soft Token",
238
- "Authy Authenticator"
239
- ) ) ) {
240
- update_option( 'mo2f_enable_2fa_prompt_on_login_page', 1 );
241
- }
 
 
 
242
  update_option( 'mo2f_login_option_updated', 1 );
243
  }
244
  }
@@ -331,9 +347,7 @@ class Miniorange_Authentication {
331
 
332
  function miniorange_auth_menu() {
333
  global $user;
334
- $user = wp_get_current_user();
335
-
336
-
337
  $roles = $user->roles;
338
  $miniorange_role = array_shift( $roles );
339
 
@@ -344,8 +358,11 @@ class Miniorange_Authentication {
344
  $admin_registration_status = get_option( 'mo_2factor_admin_registration_status' ) == 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS'
345
  ? true : false;
346
 
347
-
348
-
 
 
 
349
  if ( $admin_registration_status ) {
350
  if ( $can_current_user_manage_options && $is_customer_admin ) {
351
  $mo2fa_hook_page = $this->hookpages();
@@ -358,14 +375,13 @@ class Miniorange_Authentication {
358
  }
359
 
360
  function hookpages() {
 
361
  if(get_site_option('mo2f_enable_custom_icon')!=1)
362
- $iconurl = plugin_dir_url(__FILE__) . 'includes/images/miniorange_icon.png';
363
  else
364
  $iconurl = site_url(). '/wp-content/uploads/miniorange/plugin_icon.png';
365
  $menu_slug = 'miniOrange_2_factor_settings';
366
-
367
- add_menu_page( 'miniOrange 2 Factor Auth', get_option('mo2f_custom_plugin_name'), 'manage_options', $menu_slug, array($this,'mo_auth_login_options'), $iconurl );
368
-
369
  }
370
 
371
  function mo_auth_login_options() {
@@ -376,7 +392,7 @@ class Miniorange_Authentication {
376
  }
377
 
378
  function mo_2_factor_enable_frontend_style() {
379
- wp_enqueue_style( 'mo2f_frontend_login_style', plugins_url( 'includes/css/front_end_login.css?version='.MO2F_VERSION.'', __FILE__ ) );
380
  wp_enqueue_style( 'bootstrap_style', plugins_url( 'includes/css/bootstrap.min.css?version='.MO2F_VERSION.'', __FILE__ ) );
381
  wp_enqueue_style( 'mo_2_factor_admin_settings_phone_style', plugins_url( 'includes/css/phone.css?version='.MO2F_VERSION.'', __FILE__ ) );
382
  wp_enqueue_style( 'mo_2_factor_wpb-fa', plugins_url( 'includes/css/font-awesome.min.css', __FILE__ ) );
@@ -384,9 +400,11 @@ class Miniorange_Authentication {
384
  }
385
 
386
  function plugin_settings_style( $mo2fa_hook_page ) {
 
387
  if ( 'toplevel_page_miniOrange_2_factor_settings' != $mo2fa_hook_page ) {
388
  return;
389
  }
 
390
  wp_enqueue_style( 'mo_2_factor_admin_settings_style', plugins_url( 'includes/css/style_settings.css?version='.MO2F_VERSION.'', __FILE__ ) );
391
  wp_enqueue_style( 'mo_2_factor_admin_settings_phone_style', plugins_url( 'includes/css/phone.css?version='.MO2F_VERSION.'', __FILE__ ) );
392
  wp_enqueue_style( 'bootstrap_style', plugins_url( 'includes/css/bootstrap.min.css?version='.MO2F_VERSION.'', __FILE__ ) );
@@ -401,7 +419,7 @@ class Miniorange_Authentication {
401
  }
402
  wp_enqueue_script( 'jquery' );
403
  wp_enqueue_script( 'mo_2_factor_admin_settings_phone_script', plugins_url( 'includes/js/phone.js', __FILE__ ) );
404
- wp_enqueue_script( 'bootstrap_script', plugins_url( 'includes/js/bootstrap.min.js', dirname(__FILE__ )) );
405
  wp_enqueue_script( 'bootstrap_script_hehe', plugins_url( 'includes/js/bootstrap-tour-standalone.min.js', __FILE__ ) );
406
  wp_enqueue_script( 'mo2f_ns_admin_datatable_script', plugins_url('includes/js/jquery.dataTables.min.js', __FILE__ ), array('jquery'));
407
 
@@ -410,7 +428,7 @@ class Miniorange_Authentication {
410
  function miniorange_auth_save_settings() {
411
  if ( array_key_exists( 'page', $_REQUEST ) && $_REQUEST['page'] == 'mo_2fa_two_fa' ) {
412
  if ( ! session_id() || session_id() == '' || ! isset( $_SESSION ) ) {
413
- session_start();
414
  }
415
  }
416
 
@@ -927,35 +945,45 @@ class Miniorange_Authentication {
927
  return $error;
928
  } else {
929
  $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID );
930
- if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
931
 
932
- update_option( 'mo2f_login_option', isset( $_POST['mo2f_login_option'] ) ? $_POST['mo2f_login_option'] : 0 );
933
- update_option( 'mo2f_remember_device', isset( $_POST['mo2f_remember_device'] ) ? $_POST['mo2f_remember_device'] : 0 );
934
- if ( get_option( 'mo2f_login_option' ) == 0 ) {
935
- update_option( 'mo2f_remember_device', 0 );
936
- }
937
- update_option( 'mo2f_enable_forgotphone', isset( $_POST['mo2f_forgotphone'] ) ? $_POST['mo2f_forgotphone'] : 0 );
938
- update_option( 'mo2f_enable_login_with_2nd_factor', isset( $_POST['mo2f_login_with_username_and_2factor'] ) ? $_POST['mo2f_login_with_username_and_2factor'] : 0 );
939
- update_option( 'mo2f_enable_xmlrpc', isset( $_POST['mo2f_enable_xmlrpc'] ) ? $_POST['mo2f_enable_xmlrpc'] : 0 );
940
- if ( get_option( 'mo2f_remember_device' ) && ! get_option( 'mo2f_app_secret' ) ) {
941
- $get_app_secret = new Miniorange_Rba_Attributes();
942
- $rba_response = json_decode( $get_app_secret->mo2f_get_app_secret(), true ); //fetch app secret
943
- if ( json_last_error() == JSON_ERROR_NONE ) {
944
- if ( $rba_response['status'] == 'SUCCESS' ) {
945
- update_option( 'mo2f_app_secret', $rba_response['appSecret'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
946
  } else {
947
  update_option( 'mo2f_remember_device', 0 );
948
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_SETTINGS" ) );
949
  $this->mo_auth_show_error_message();
950
  }
951
- } else {
952
- update_option( 'mo2f_remember_device', 0 );
953
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_SETTINGS" ) );
954
- $this->mo_auth_show_error_message();
955
  }
 
 
956
  }
957
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "SETTINGS_SAVED" ) );
958
- $this->mo_auth_show_success_message();
959
  } else {
960
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQUEST" ) );
961
  $this->mo_auth_show_error_message();
@@ -1411,6 +1439,22 @@ class Miniorange_Authentication {
1411
 
1412
  return $error;
1413
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1414
  $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
1415
  $mo2f_EmailVerification_config_status = $Mo2fdbQueries->get_user_detail( 'mo2f_EmailVerification_config_status', $user->ID );
1416
  if ( ! current_user_can( 'manage_options' ) && $mo2f_configured_2FA_method == 'OUT OF BAND EMAIL' ) {
@@ -1430,7 +1474,7 @@ class Miniorange_Authentication {
1430
  'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS',
1431
  'mo2f_EmailVerification_config_status' => true
1432
  ) );
1433
-
1434
  $this->mo_auth_show_success_message();
1435
  }
1436
 
@@ -1500,7 +1544,7 @@ class Miniorange_Authentication {
1500
  $this->mo_auth_show_error_message();
1501
 
1502
  }
1503
-
1504
  }
1505
  }else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_google_appname' ) {
1506
  $nonce = $_POST['mo2f_google_appname_nonce'];
@@ -1526,18 +1570,34 @@ class Miniorange_Authentication {
1526
  } else {
1527
  $otpToken = $_POST['google_token'];
1528
  $ga_secret = isset( $_POST['google_auth_secret'] ) ? $_POST['google_auth_secret'] : null;
 
1529
  if ( MO2f_Utility::mo2f_check_number_length( $otpToken ) ) {
1530
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1531
-
 
 
 
 
 
 
 
 
 
 
 
1532
  $google_auth = new Miniorange_Rba_Attributes();
1533
  $google_response = json_decode( $google_auth->mo2f_validate_google_auth( $email, $otpToken, $ga_secret ), true );
 
1534
  if ( json_last_error() == JSON_ERROR_NONE ) {
1535
  if ( $google_response['status'] == 'SUCCESS' ) {
1536
- $enduser = new Two_Factor_Setup();
1537
- $response = json_decode( $enduser->mo2f_update_userinfo( $email, "GOOGLE AUTHENTICATOR", null, null, null ), true );
 
 
 
 
1538
 
1539
-
1540
- if ( json_last_error() == JSON_ERROR_NONE ) {
1541
 
1542
  if ( $response['status'] == 'SUCCESS' ) {
1543
 
@@ -1576,7 +1636,7 @@ class Miniorange_Authentication {
1576
  $this->mo_auth_show_error_message();
1577
 
1578
  }
1579
-
1580
  } else {
1581
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ONLY_DIGITS_ALLOWED" ) );
1582
  $this->mo_auth_show_error_message();
@@ -1666,22 +1726,26 @@ class Miniorange_Authentication {
1666
  $this->mo_auth_show_error_message();
1667
  }
1668
  }
1669
- }else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_kba' ) {
1670
-
1671
  $nonce = $_POST['mo2f_save_kba_nonce'];
1672
-
1673
  if ( ! wp_verify_nonce( $nonce, 'mo2f-save-kba-nonce' ) ) {
1674
  $error = new WP_Error();
1675
  $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1676
 
1677
  return $error;
1678
- } else {
1679
-
1680
- 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'] ) ) {
 
 
 
 
 
 
 
1681
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1682
  $this->mo_auth_show_error_message();
1683
-
1684
-
1685
  return;
1686
  }
1687
 
@@ -1692,65 +1756,87 @@ class Miniorange_Authentication {
1692
  $kba_q3 = sanitize_text_field( $_POST['mo2f_kbaquestion_3'] );
1693
  $kba_a3 = sanitize_text_field( $_POST['mo2f_kba_ans3'] );
1694
 
1695
-
1696
  if ( strcasecmp( $kba_q1, $kba_q2 ) == 0 || strcasecmp( $kba_q2, $kba_q3 ) == 0 || strcasecmp( $kba_q3, $kba_q1 ) == 0 ) {
1697
  update_option( 'mo2f_message', 'The questions you select must be unique.' );
1698
  $this->mo_auth_show_error_message();
1699
-
1700
-
1701
  return;
1702
  }
1703
- $kba_q1 = addcslashes( stripslashes( $kba_q1 ), '"\\' );
1704
- $kba_a1 = addcslashes( stripslashes( $kba_a1 ), '"\\' );
1705
- $kba_q2 = addcslashes( stripslashes( $kba_q2 ), '"\\' );
1706
- $kba_a2 = addcslashes( stripslashes( $kba_a2 ), '"\\' );
1707
- $kba_q3 = addcslashes( stripslashes( $kba_q3 ), '"\\' );
1708
- $kba_a3 = addcslashes( stripslashes( $kba_a3 ), '"\\' );
1709
-
1710
- $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1711
- $kba_registration = new Two_Factor_Setup();
1712
- $kba_reg_reponse = json_decode( $kba_registration->register_kba_details( $email, $kba_q1, $kba_a1, $kba_q2, $kba_a2, $kba_q3, $kba_a3 ), true );
1713
- if ( json_last_error() == JSON_ERROR_NONE ) {
1714
- if ( $kba_reg_reponse['status'] == 'SUCCESS' ) {
1715
- if ( isset( $_POST['mobile_kba_option'] ) && $_POST['mobile_kba_option'] == 'mo2f_request_for_kba_as_emailbackup' ) {
1716
- MO2f_Utility::unset_session_variables( 'mo2f_mobile_support' );
 
 
 
 
 
 
 
 
 
 
1717
 
1718
- delete_user_meta( $user->ID, 'configure_2FA' );
1719
- delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
 
 
 
 
 
1720
 
1721
- $message = mo2f_lt( 'Your KBA as alternate 2 factor is configured successfully.' );
1722
- update_option( 'mo2f_message', $message );
1723
- $this->mo_auth_show_success_message();
1724
 
1725
- } else {
1726
- $enduser = new Two_Factor_Setup();
1727
- $response = json_decode( $enduser->mo2f_update_userinfo( $email, 'KBA', null, null, null ), true );
1728
- if ( json_last_error() == JSON_ERROR_NONE ) {
1729
- if ( $response['status'] == 'ERROR' ) {
1730
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1731
- $this->mo_auth_show_error_message();
1732
 
1733
- } else if ( $response['status'] == 'SUCCESS' ) {
1734
- delete_user_meta( $user->ID, 'configure_2FA' );
 
 
 
 
 
1735
 
1736
- $Mo2fdbQueries->update_user_details( $user->ID, array(
1737
- 'mo2f_SecurityQuestions_config_status' => true,
1738
- 'mo2f_configured_2FA_method' => "Security Questions",
1739
- 'mo_2factor_user_registration_status' => "MO_2_FACTOR_PLUGIN_SETTINGS"
1740
- ) );
1741
- // $this->mo_auth_show_success_message();
1742
- mo2f_display_test_2fa_notification($user);
1743
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1744
  } else {
1745
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1746
  $this->mo_auth_show_error_message();
1747
 
1748
  }
1749
- } else {
1750
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1751
- $this->mo_auth_show_error_message();
1752
-
1753
  }
 
 
 
 
 
 
1754
  }
1755
  } else {
1756
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_KBA" ) );
@@ -1758,19 +1844,10 @@ class Miniorange_Authentication {
1758
 
1759
 
1760
  return;
1761
- }
1762
- } else {
1763
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_KBA" ) );
1764
- $this->mo_auth_show_error_message();
1765
-
1766
 
1767
- return;
1768
  }
1769
- }
1770
-
1771
-
1772
  }else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_kba_details' ) {
1773
-
1774
  $nonce = $_POST['mo2f_validate_kba_details_nonce'];
1775
 
1776
  if ( ! wp_verify_nonce( $nonce, 'mo2f-validate-kba-details-nonce' ) ) {
@@ -1779,7 +1856,6 @@ class Miniorange_Authentication {
1779
 
1780
  return $error;
1781
  } else {
1782
-
1783
  $kba_ans_1 = '';
1784
  $kba_ans_2 = '';
1785
  if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_answer_1'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_answer_1'] ) ) {
@@ -1791,7 +1867,6 @@ class Miniorange_Authentication {
1791
  $kba_ans_1 = sanitize_text_field( $_POST['mo2f_answer_1'] );
1792
  $kba_ans_2 = sanitize_text_field( $_POST['mo2f_answer_2'] );
1793
  }
1794
-
1795
  //if the php session folder has insufficient permissions, temporary options to be used
1796
  $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' );
1797
 
@@ -1806,7 +1881,6 @@ class Miniorange_Authentication {
1806
 
1807
  $kba_validate = new Customer_Setup();
1808
  $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 );
1809
-
1810
  if ( json_last_error() == JSON_ERROR_NONE ) {
1811
  if ( strcasecmp( $kba_validate_response['status'], 'SUCCESS' ) == 0 ) {
1812
  unset( $_SESSION['mo_2_factor_kba_questions'] );
@@ -1823,7 +1897,6 @@ class Miniorange_Authentication {
1823
  }
1824
  }
1825
  }
1826
-
1827
  }else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_otp_over_sms_send_otp' ) { // sendin otp for configuring OTP over SMS
1828
 
1829
  $nonce = $_POST['mo2f_configure_otp_over_sms_send_otp_nonce'];
@@ -1963,23 +2036,38 @@ class Miniorange_Authentication {
1963
  }else if ( ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_free_plan_auth_methods' ) ) {// user clicks on Set 2-Factor method
1964
 
1965
  $nonce = $_POST['miniorange_save_form_auth_methods_nonce'];
1966
-
1967
  if ( ! wp_verify_nonce( $nonce, 'miniorange-save-form-auth-methods-nonce' ) ) {
1968
  $error = new WP_Error();
1969
  $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1970
-
1971
  return $error;
1972
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1973
  $is_customer_registered = $Mo2fdbQueries->get_user_detail( 'user_registration_with_miniorange', $user->ID ) == 'SUCCESS' ? true : false;
1974
-
1975
  $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" );
1976
  update_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', $selected_2FA_method );
1977
-
 
1978
  if ( $is_customer_registered ) {
1979
  $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" );
1980
  $selected_action = isset( $_POST['mo2f_selected_action_free_plan'] ) ? $_POST['mo2f_selected_action_free_plan'] : $_POST['mo2f_selected_action_standard_plan'];
1981
  $user_phone = '';
1982
-
1983
  if ( isset( $_SESSION['user_phone'] ) ) {
1984
  $user_phone = $_SESSION['user_phone'] != 'false' ? $_SESSION['user_phone'] : $Mo2fdbQueries->get_user_detail( 'mo2f_user_phone', $user->ID );
1985
  }
@@ -1995,12 +2083,20 @@ class Miniorange_Authentication {
1995
  $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo2f_configured_2FA_method' => $selected_2FA_method ) );
1996
 
1997
  // update the server
1998
- $this->mo2f_save_2_factor_method( $user, $selected_2FA_method );
1999
-
2000
  if ( in_array( $selected_2FA_method, array(
2001
- "Google Authenticator",
2002
  "miniOrange Soft Token",
2003
- "Authy Authenticator"
 
 
 
 
 
 
 
 
2004
  ) ) ) {
2005
 
2006
  } else {
@@ -2008,13 +2104,11 @@ class Miniorange_Authentication {
2008
  }
2009
 
2010
  }
2011
-
2012
  } else if ( $selected_action == "configure2factor" ) {
2013
 
2014
  //show configuration form of respective Two Factor method
2015
  update_user_meta( $user->ID, 'configure_2FA', 1 );
2016
  update_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', $selected_2FA_method );
2017
-
2018
  }
2019
 
2020
  } else {
@@ -2075,7 +2169,9 @@ class Miniorange_Authentication {
2075
  } else {
2076
  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 );
2077
  }
2078
- }else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo_2factor_test_authentication_method' ) {
 
 
2079
  //network security feature
2080
  $nonce = $_POST['mo_2factor_test_authentication_method_nonce'];
2081
 
@@ -2096,7 +2192,17 @@ class Miniorange_Authentication {
2096
  $api_key = get_option( 'mo2f_api_key' );
2097
 
2098
  if ( $selected_2FA_method == 'Security Questions' ) {
2099
- $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
 
 
 
 
 
 
 
 
 
 
2100
  if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate KBA Questions*/
2101
  if ( $response['status'] == 'SUCCESS' ) {
2102
  $_SESSION['mo2f_transactionId'] = $response['txId'];
@@ -2120,7 +2226,7 @@ class Miniorange_Authentication {
2120
  $this->mo_auth_show_error_message();
2121
 
2122
  }
2123
-
2124
 
2125
  } else if ( $selected_2FA_method == 'miniOrange Push Notification' ) {
2126
  $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
@@ -2351,7 +2457,7 @@ class Miniorange_Authentication {
2351
  $enduser = new Two_Factor_Setup();
2352
  $enduser->mo2f_update_userinfo( $email, 'OUT OF BAND EMAIL', null, 'API_2FA', true );
2353
 
2354
- update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ACCOUNT_RETRIEVED_SUCCESSFULLY" ) . ' <b>' . Mo2fConstants:: langTranslate( "EMAIL_VERFI" ) . '</b> ' . Mo2fConstants:: langTranslate( "DEFAULT_2ND_FACTOR" ) . ' <a href=\"admin.php?page=mo_2fa_two_fa\" >' . Mo2fConstants:: langTranslate( "CLICK_HERE" ) . '</a> ' . Mo2fConstants:: langTranslate( "CONFIGURE_2FA" ) );
2355
  $this->mo_auth_show_success_message();
2356
  } else {
2357
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_CREATE_ACC_OTP" ) );
@@ -2591,7 +2697,86 @@ class Miniorange_Authentication {
2591
  }
2592
 
2593
  function miniorange_email_verification_call( $current_user ) {
2594
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2595
  global $Mo2fdbQueries;
2596
  $challengeMobile = new Customer_Setup();
2597
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $current_user->ID );
@@ -2617,6 +2802,7 @@ class Miniorange_Authentication {
2617
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
2618
  $this->mo_auth_show_error_message();
2619
  }
 
2620
  }
2621
 
2622
  function mo_auth_activate() {
@@ -2668,4 +2854,4 @@ function mo2f_is_customer_registered() {
2668
  }
2669
  }
2670
  new Miniorange_Authentication;
2671
- ?>
1
  <?php
2
 
3
+ include 'two_fa_pass2login.php';
4
  include dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'views'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_setup_notification.php';
5
  include 'class_miniorange_2fa_strong_password.php';
6
+
7
  class Miniorange_Authentication {
8
 
9
  private $defaultCustomerKey = "16555";
14
  // add_action( 'admin_notices', array( $this, 'prompt_user_to_setup_two_factor' ) );
15
  add_action( 'admin_init', array( $this, 'miniorange_auth_save_settings' ) );
16
  add_action( 'plugins_loaded', array( $this, 'mo2f_update_db_check' ) );
17
+
18
  global $wp_roles;
19
  if ( ! isset( $wp_roles ) ) {
20
  $wp_roles = new WP_Roles();
21
  }
 
22
  if ( get_option( 'mo2f_activate_plugin' ) == 1 ) {
23
+
24
  $mo2f_rba_attributes = new Miniorange_Rba_Attributes();
25
  $pass2fa_login = new Miniorange_Password_2Factor_Login();
26
  $mo2f_2factor_setup = new Two_Factor_Setup();
47
  'miniorange_pass2login_form_fields'
48
  ), 10, 5 );
49
  add_filter( 'mo2f_gauth_service', array( $mo2f_rba_attributes, 'mo2f_google_auth_service' ), 10, 1 );
 
 
50
  if ( get_option( 'mo2f_login_option' ) ) { //password + 2nd factor enabled
51
+ if ( get_option( 'mo_2factor_admin_registration_status' ) == 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' or MO2F_IS_ONPREM ) {
52
 
53
  remove_filter( 'authenticate', 'wp_authenticate_username_password', 20 );
54
+
55
  add_filter( 'authenticate', array( $pass2fa_login, 'mo2f_check_username_password' ), 99999, 4 );
56
  add_action( 'init', array( $pass2fa_login, 'miniorange_pass2login_redirect' ) );
57
  add_action( 'login_form', array(
70
  $pass2fa_login,
71
  'mo_2_factor_enable_jquery_default_login'
72
  ) );
73
+
74
+ add_action( 'woocommerce_login_form_end', array(
 
75
  $pass2fa_login,
76
  'mo_2_factor_pass2login_show_wp_login_form'
77
  ) );
 
 
 
 
 
 
 
78
  add_action( 'wp_enqueue_scripts', array(
79
  $pass2fa_login,
80
  'mo_2_factor_enable_jquery_default_login'
98
 
99
  } else { //login with phone enabled
100
 
101
+ if ( get_option( 'mo_2factor_admin_registration_status' ) == 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS' or MO2F_IS_ONPREM) {
102
 
103
  $mobile_login = new Miniorange_Mobile_Login();
104
+ add_action( 'login_form', array( $mobile_login, 'miniorange_login_form_fields' ), 99999,10 );
105
  add_action( 'login_footer', array( $mobile_login, 'miniorange_login_footer_form' ) );
106
 
107
  remove_filter( 'authenticate', 'wp_authenticate_username_password', 20 );
118
  }
119
 
120
  function mo2f_update_db_check() {
121
+
122
+ $userid = wp_get_current_user()->ID;
123
+ add_option('mo2f_onprem_admin' , $userid );
124
+ // Deciding on On-Premise solution
125
+ $is_NC=get_option( 'mo2f_is_NC' );
126
+ $is_NNC=get_option( 'mo2f_is_NNC' );
127
+ // Old users
128
+ if ( get_option( 'mo2f_customerKey' ) && ! $is_NC )
129
+ add_option( 'is_onprem', 0 );
130
+
131
+ //new users using cloud
132
+ if(get_option( 'mo2f_customerKey' ) && $is_NC && $is_NNC)
133
+ add_option( 'is_onprem', 0 );
134
+
135
+ if(get_option( 'mo2f_app_secret' ) && $is_NC && $is_NNC){
136
+ add_option( 'is_onprem', 0 );
137
+ }else{
138
+ add_option( 'is_onprem', 1 );
139
+
140
+ }
141
  if(get_option('mo2f_network_features',"not_exits")=="not_exits"){
142
  do_action('mo2f_network_create_db');
143
  update_option('mo2f_network_features',1);
245
  if ( $check_if_user_column_exists ) {
246
  $selected_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user_id );
247
 
248
+ // if ( in_array( $selected_2FA_method, array(
249
+ // "Google Authenticator",
250
+ // "miniOrange Soft Token",
251
+ // "Authy Authenticator",
252
+ // "Security Questions",
253
+ // "miniOrange Push Notification",
254
+ // "miniOrange QR Code Authentication"
255
+ // ) ) ) {
256
+ // update_option( 'mo2f_enable_2fa_prompt_on_login_page', 1 );
257
+ // }
258
  update_option( 'mo2f_login_option_updated', 1 );
259
  }
260
  }
347
 
348
  function miniorange_auth_menu() {
349
  global $user;
350
+ $user = wp_get_current_user();
 
 
351
  $roles = $user->roles;
352
  $miniorange_role = array_shift( $roles );
353
 
358
  $admin_registration_status = get_option( 'mo_2factor_admin_registration_status' ) == 'MO_2_FACTOR_CUSTOMER_REGISTERED_SUCCESS'
359
  ? true : false;
360
 
361
+ if(MO2F_IS_ONPREM)
362
+ {
363
+ $can_current_user_manage_options = true; // changes by prdp
364
+ $is_customer_admin = true;
365
+ }
366
  if ( $admin_registration_status ) {
367
  if ( $can_current_user_manage_options && $is_customer_admin ) {
368
  $mo2fa_hook_page = $this->hookpages();
375
  }
376
 
377
  function hookpages() {
378
+ $url = explode('handler',plugin_dir_url(__FILE__));
379
  if(get_site_option('mo2f_enable_custom_icon')!=1)
380
+ $iconurl = $url[0] . '/includes/images/miniorange_icon.png';
381
  else
382
  $iconurl = site_url(). '/wp-content/uploads/miniorange/plugin_icon.png';
383
  $menu_slug = 'miniOrange_2_factor_settings';
384
+ add_menu_page( 'miniOrange 2 Factor Auth', get_option('mo2f_custom_plugin_name'), 'read', $menu_slug, array($this,'mo_auth_login_options'), $iconurl );
 
 
385
  }
386
 
387
  function mo_auth_login_options() {
392
  }
393
 
394
  function mo_2_factor_enable_frontend_style() {
395
+ wp_enqueue_style( 'mo2f_frontend_login_style', plugins_url( 'includes/css/front_end_login.css?version='.MO2F_VERSION.'', __FILE__ ) );
396
  wp_enqueue_style( 'bootstrap_style', plugins_url( 'includes/css/bootstrap.min.css?version='.MO2F_VERSION.'', __FILE__ ) );
397
  wp_enqueue_style( 'mo_2_factor_admin_settings_phone_style', plugins_url( 'includes/css/phone.css?version='.MO2F_VERSION.'', __FILE__ ) );
398
  wp_enqueue_style( 'mo_2_factor_wpb-fa', plugins_url( 'includes/css/font-awesome.min.css', __FILE__ ) );
400
  }
401
 
402
  function plugin_settings_style( $mo2fa_hook_page ) {
403
+
404
  if ( 'toplevel_page_miniOrange_2_factor_settings' != $mo2fa_hook_page ) {
405
  return;
406
  }
407
+
408
  wp_enqueue_style( 'mo_2_factor_admin_settings_style', plugins_url( 'includes/css/style_settings.css?version='.MO2F_VERSION.'', __FILE__ ) );
409
  wp_enqueue_style( 'mo_2_factor_admin_settings_phone_style', plugins_url( 'includes/css/phone.css?version='.MO2F_VERSION.'', __FILE__ ) );
410
  wp_enqueue_style( 'bootstrap_style', plugins_url( 'includes/css/bootstrap.min.css?version='.MO2F_VERSION.'', __FILE__ ) );
419
  }
420
  wp_enqueue_script( 'jquery' );
421
  wp_enqueue_script( 'mo_2_factor_admin_settings_phone_script', plugins_url( 'includes/js/phone.js', __FILE__ ) );
422
+ wp_enqueue_script( 'bootstrap_script', plugins_url( 'includes/js/bootstrap.min.js', __FILE__ ) );
423
  wp_enqueue_script( 'bootstrap_script_hehe', plugins_url( 'includes/js/bootstrap-tour-standalone.min.js', __FILE__ ) );
424
  wp_enqueue_script( 'mo2f_ns_admin_datatable_script', plugins_url('includes/js/jquery.dataTables.min.js', __FILE__ ), array('jquery'));
425
 
428
  function miniorange_auth_save_settings() {
429
  if ( array_key_exists( 'page', $_REQUEST ) && $_REQUEST['page'] == 'mo_2fa_two_fa' ) {
430
  if ( ! session_id() || session_id() == '' || ! isset( $_SESSION ) ) {
431
+ session_start();
432
  }
433
  }
434
 
945
  return $error;
946
  } else {
947
  $mo_2factor_user_registration_status = $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID );
948
+ if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' or MO2F_IS_ONPREM ) {
949
 
950
+ if($_POST['mo2f_login_option'] == 0 && get_option('mo2f_enable_2fa_prompt_on_login_page')){
951
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "LOGIN_WITH_2ND_FACTOR" ) );
952
+ $this->mo_auth_show_error_message();
953
+ }else{
954
+ update_option( 'mo2f_login_option', isset( $_POST['mo2f_login_option'] ) ? $_POST['mo2f_login_option'] : 0 );
955
+ update_option( 'mo2f_remember_device', isset( $_POST['mo2f_remember_device'] ) ? $_POST['mo2f_remember_device'] : 0 );
956
+ if ( get_option( 'mo2f_login_option' ) == 0 ) {
957
+ update_option( 'mo2f_remember_device', 0 );
958
+ }
959
+ if(isset($_POST['mo2f_enable_login_with_2nd_factor']))
960
+ {
961
+ update_option('mo2f_login_option',1);
962
+ }
963
+ update_option( 'mo2f_enable_forgotphone', isset( $_POST['mo2f_forgotphone'] ) ? $_POST['mo2f_forgotphone'] : 0 );
964
+ update_option( 'mo2f_enable_login_with_2nd_factor', isset( $_POST['mo2f_login_with_username_and_2factor'] ) ? $_POST['mo2f_login_with_username_and_2factor'] : 0 );
965
+ update_option( 'mo2f_enable_xmlrpc', isset( $_POST['mo2f_enable_xmlrpc'] ) ? $_POST['mo2f_enable_xmlrpc'] : 0 );
966
+ if ( get_option( 'mo2f_remember_device' ) && ! get_option( 'mo2f_app_secret' ) ) {
967
+ $get_app_secret = new Miniorange_Rba_Attributes();
968
+ $rba_response = json_decode( $get_app_secret->mo2f_get_app_secret(), true ); //fetch app secret
969
+ if ( json_last_error() == JSON_ERROR_NONE ) {
970
+ if ( $rba_response['status'] == 'SUCCESS' ) {
971
+ update_option( 'mo2f_app_secret', $rba_response['appSecret'] );
972
+ } else {
973
+ update_option( 'mo2f_remember_device', 0 );
974
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_SETTINGS" ) );
975
+ $this->mo_auth_show_error_message();
976
+ }
977
  } else {
978
  update_option( 'mo2f_remember_device', 0 );
979
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_SETTINGS" ) );
980
  $this->mo_auth_show_error_message();
981
  }
 
 
 
 
982
  }
983
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "SETTINGS_SAVED" ) );
984
+ $this->mo_auth_show_success_message();
985
  }
986
+
 
987
  } else {
988
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQUEST" ) );
989
  $this->mo_auth_show_error_message();
1439
 
1440
  return $error;
1441
  } else {
1442
+ $show = 1;
1443
+ if(MO2F_IS_ONPREM )
1444
+ {
1445
+ $txid = $_POST['TxidEmail'];
1446
+ $status = get_option($txid);
1447
+ if($status != '')
1448
+ {
1449
+ if($status != 1)
1450
+ {
1451
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_EMAIL_VER_REQ" ));
1452
+ $show = 0;
1453
+ $this->mo_auth_show_error_message();
1454
+
1455
+ }
1456
+ }
1457
+ }
1458
  $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
1459
  $mo2f_EmailVerification_config_status = $Mo2fdbQueries->get_user_detail( 'mo2f_EmailVerification_config_status', $user->ID );
1460
  if ( ! current_user_can( 'manage_options' ) && $mo2f_configured_2FA_method == 'OUT OF BAND EMAIL' ) {
1474
  'mo_2factor_user_registration_status' => 'MO_2_FACTOR_PLUGIN_SETTINGS',
1475
  'mo2f_EmailVerification_config_status' => true
1476
  ) );
1477
+ if($show)
1478
  $this->mo_auth_show_success_message();
1479
  }
1480
 
1544
  $this->mo_auth_show_error_message();
1545
 
1546
  }
1547
+ //}
1548
  }
1549
  }else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_google_appname' ) {
1550
  $nonce = $_POST['mo2f_google_appname_nonce'];
1570
  } else {
1571
  $otpToken = $_POST['google_token'];
1572
  $ga_secret = isset( $_POST['google_auth_secret'] ) ? $_POST['google_auth_secret'] : null;
1573
+
1574
  if ( MO2f_Utility::mo2f_check_number_length( $otpToken ) ) {
1575
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1576
+ $onprem = MO2F_IS_ONPREM;
1577
+ if($onprem)
1578
+ {
1579
+ $twofactor_transactions = new Mo2fDB;
1580
+ $exceeded = $twofactor_transactions->check_user_limit_exceeded($user_id);
1581
+
1582
+ if($exceeded){
1583
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "USER_LIMIT_EXCEEDED" ) );
1584
+ $this->mo_auth_show_error_message();
1585
+ return;
1586
+ }
1587
+ }
1588
  $google_auth = new Miniorange_Rba_Attributes();
1589
  $google_response = json_decode( $google_auth->mo2f_validate_google_auth( $email, $otpToken, $ga_secret ), true );
1590
+
1591
  if ( json_last_error() == JSON_ERROR_NONE ) {
1592
  if ( $google_response['status'] == 'SUCCESS' ) {
1593
+ if($onprem != 1){
1594
+ $enduser = new Two_Factor_Setup();
1595
+ $response = json_decode( $enduser->mo2f_update_userinfo( $email, "GOOGLE AUTHENTICATOR", null, null, null ), true );
1596
+ }else{
1597
+ $response = $google_response;
1598
+ }
1599
 
1600
+ if ( json_last_error() == JSON_ERROR_NONE || MO2F_IS_ONPREM ) {
 
1601
 
1602
  if ( $response['status'] == 'SUCCESS' ) {
1603
 
1636
  $this->mo_auth_show_error_message();
1637
 
1638
  }
1639
+ //}
1640
  } else {
1641
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ONLY_DIGITS_ALLOWED" ) );
1642
  $this->mo_auth_show_error_message();
1726
  $this->mo_auth_show_error_message();
1727
  }
1728
  }
1729
+ }
1730
+ else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_kba' ) {
1731
  $nonce = $_POST['mo2f_save_kba_nonce'];
 
1732
  if ( ! wp_verify_nonce( $nonce, 'mo2f-save-kba-nonce' ) ) {
1733
  $error = new WP_Error();
1734
  $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
1735
 
1736
  return $error;
1737
+ }
1738
+ $twofactor_transactions = new Mo2fDB;
1739
+ $exceeded = $twofactor_transactions->check_user_limit_exceeded($user_id);
1740
+
1741
+ if($exceeded){
1742
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "USER_LIMIT_EXCEEDED" ) );
1743
+ $this->mo_auth_show_error_message();
1744
+ return;
1745
+ }
1746
+ 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'] ) ) {
1747
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_ENTRY" ) );
1748
  $this->mo_auth_show_error_message();
 
 
1749
  return;
1750
  }
1751
 
1756
  $kba_q3 = sanitize_text_field( $_POST['mo2f_kbaquestion_3'] );
1757
  $kba_a3 = sanitize_text_field( $_POST['mo2f_kba_ans3'] );
1758
 
 
1759
  if ( strcasecmp( $kba_q1, $kba_q2 ) == 0 || strcasecmp( $kba_q2, $kba_q3 ) == 0 || strcasecmp( $kba_q3, $kba_q1 ) == 0 ) {
1760
  update_option( 'mo2f_message', 'The questions you select must be unique.' );
1761
  $this->mo_auth_show_error_message();
 
 
1762
  return;
1763
  }
1764
+ $kba_q1 = addcslashes( stripslashes( $kba_q1 ), '"\\' );
1765
+ $kba_q2 = addcslashes( stripslashes( $kba_q2 ), '"\\' );
1766
+ $kba_q3 = addcslashes( stripslashes( $kba_q3 ), '"\\' );
1767
+ if(get_site_option('is_onprem')){
1768
+
1769
+ $kba_a1 = md5(addcslashes( stripslashes( $kba_a1 ), '"\\' ));
1770
+ $kba_a2 = md5(addcslashes( stripslashes( $kba_a2 ), '"\\' ));
1771
+ $kba_a3 = md5(addcslashes( stripslashes( $kba_a3 ), '"\\' ));
1772
+
1773
+ $question_answer = array($kba_q1 => $kba_a1 ,$kba_q2 => $kba_a2 , $kba_q3 => $kba_a3 );
1774
+ update_user_meta( $user_id , 'mo2f_kba_challenge', $question_answer );
1775
+ delete_user_meta( $user_id, 'configure_2FA' );
1776
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
1777
+ 'mo2f_SecurityQuestions_config_status' => true,
1778
+ 'mo2f_configured_2FA_method' => "Security Questions",
1779
+ 'mo_2factor_user_registration_status' => "MO_2_FACTOR_PLUGIN_SETTINGS"
1780
+ ) );
1781
+ update_user_meta($user->ID,'currentMethod','Security Questions');
1782
+ mo2f_display_test_2fa_notification($user);
1783
+ }
1784
+ else{
1785
+ $kba_a1 = addcslashes( stripslashes( $kba_a1 ), '"\\' );
1786
+ $kba_a2 = addcslashes( stripslashes( $kba_a2 ), '"\\' );
1787
+ $kba_a3 = addcslashes( stripslashes( $kba_a3 ), '"\\' );
1788
 
1789
+ $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $user->ID );
1790
+ $kba_registration = new Two_Factor_Setup();
1791
+ $kba_reg_reponse = json_decode( $kba_registration->register_kba_details( $email, $kba_q1, $kba_a1, $kba_q2, $kba_a2, $kba_q3, $kba_a3 ), true );
1792
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1793
+ if ( $kba_reg_reponse['status'] == 'SUCCESS' ) {
1794
+ if ( isset( $_POST['mobile_kba_option'] ) && $_POST['mobile_kba_option'] == 'mo2f_request_for_kba_as_emailbackup' ) {
1795
+ MO2f_Utility::unset_session_variables( 'mo2f_mobile_support' );
1796
 
1797
+ delete_user_meta( $user->ID, 'configure_2FA' );
1798
+ delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure' );
 
1799
 
1800
+ $message = mo2f_lt( 'Your KBA as alternate 2 factor is configured successfully.' );
1801
+ update_option( 'mo2f_message', $message );
1802
+ $this->mo_auth_show_success_message();
 
 
 
 
1803
 
1804
+ } else {
1805
+ $enduser = new Two_Factor_Setup();
1806
+ $response = json_decode( $enduser->mo2f_update_userinfo( $email, 'KBA', null, null, null ), true );
1807
+ if ( json_last_error() == JSON_ERROR_NONE ) {
1808
+ if ( $response['status'] == 'ERROR' ) {
1809
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( $response['message'] ) );
1810
+ $this->mo_auth_show_error_message();
1811
 
1812
+ } else if ( $response['status'] == 'SUCCESS' ) {
1813
+ delete_user_meta( $user->ID, 'configure_2FA' );
 
 
 
 
 
1814
 
1815
+ $Mo2fdbQueries->update_user_details( $user->ID, array(
1816
+ 'mo2f_SecurityQuestions_config_status' => true,
1817
+ 'mo2f_configured_2FA_method' => "Security Questions",
1818
+ 'mo_2factor_user_registration_status' => "MO_2_FACTOR_PLUGIN_SETTINGS"
1819
+ ) );
1820
+ // $this->mo_auth_show_success_message();
1821
+ mo2f_display_test_2fa_notification($user);
1822
+
1823
+ }else {
1824
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_DURING_PROCESS" ) );
1825
+ $this->mo_auth_show_error_message();
1826
+
1827
+ }
1828
  } else {
1829
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
1830
  $this->mo_auth_show_error_message();
1831
 
1832
  }
 
 
 
 
1833
  }
1834
+ } else {
1835
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_KBA" ) );
1836
+ $this->mo_auth_show_error_message();
1837
+
1838
+
1839
+ return;
1840
  }
1841
  } else {
1842
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_WHILE_SAVING_KBA" ) );
1844
 
1845
 
1846
  return;
1847
+ }
 
 
 
 
1848
 
 
1849
  }
 
 
 
1850
  }else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_validate_kba_details' ) {
 
1851
  $nonce = $_POST['mo2f_validate_kba_details_nonce'];
1852
 
1853
  if ( ! wp_verify_nonce( $nonce, 'mo2f-validate-kba-details-nonce' ) ) {
1856
 
1857
  return $error;
1858
  } else {
 
1859
  $kba_ans_1 = '';
1860
  $kba_ans_2 = '';
1861
  if ( MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_answer_1'] ) || MO2f_Utility::mo2f_check_empty_or_null( $_POST['mo2f_answer_1'] ) ) {
1867
  $kba_ans_1 = sanitize_text_field( $_POST['mo2f_answer_1'] );
1868
  $kba_ans_2 = sanitize_text_field( $_POST['mo2f_answer_2'] );
1869
  }
 
1870
  //if the php session folder has insufficient permissions, temporary options to be used
1871
  $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' );
1872
 
1881
 
1882
  $kba_validate = new Customer_Setup();
1883
  $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 );
 
1884
  if ( json_last_error() == JSON_ERROR_NONE ) {
1885
  if ( strcasecmp( $kba_validate_response['status'], 'SUCCESS' ) == 0 ) {
1886
  unset( $_SESSION['mo_2_factor_kba_questions'] );
1897
  }
1898
  }
1899
  }
 
1900
  }else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_configure_otp_over_sms_send_otp' ) { // sendin otp for configuring OTP over SMS
1901
 
1902
  $nonce = $_POST['mo2f_configure_otp_over_sms_send_otp_nonce'];
2036
  }else if ( ( isset( $_POST['option'] ) && $_POST['option'] == 'mo2f_save_free_plan_auth_methods' ) ) {// user clicks on Set 2-Factor method
2037
 
2038
  $nonce = $_POST['miniorange_save_form_auth_methods_nonce'];
2039
+
2040
  if ( ! wp_verify_nonce( $nonce, 'miniorange-save-form-auth-methods-nonce' ) ) {
2041
  $error = new WP_Error();
2042
  $error->add( 'empty_username', '<strong>' . mo2f_lt( 'ERROR' ) . '</strong>: ' . mo2f_lt( 'Invalid Request.' ) );
 
2043
  return $error;
2044
  } else {
2045
+ $configuredMethod = sanitize_text_field($_POST['mo2f_configured_2FA_method_free_plan']);
2046
+ $selectedAction = sanitize_text_field($_POST['mo2f_selected_action_free_plan']);
2047
+ if(MO2F_IS_ONPREM and $configuredMethod =='EmailVerification')
2048
+ {
2049
+ update_user_meta($user->ID,'currentMethod','Email Verification');
2050
+ mo2f_display_test_2fa_notification($user);
2051
+ }
2052
+ else if($selectedAction == 'select2factor' and MO2F_IS_ONPREM)
2053
+ {
2054
+ if($configuredMethod == 'SecurityQuestions')
2055
+ update_user_meta($user->ID,'currentMethod','Security Questions');
2056
+ else if($configuredMethod == 'GoogleAuthenticator')
2057
+ update_user_meta($user->ID,'currentMethod','Google Authenticator');
2058
+ else
2059
+ update_user_meta($user->ID,'currentMethod',$configuredMethod);
2060
+ mo2f_display_test_2fa_notification($user);
2061
+ }
2062
  $is_customer_registered = $Mo2fdbQueries->get_user_detail( 'user_registration_with_miniorange', $user->ID ) == 'SUCCESS' ? true : false;
 
2063
  $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" );
2064
  update_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', $selected_2FA_method );
2065
+ if(MO2F_IS_ONPREM)
2066
+ $is_customer_registered = 1;
2067
  if ( $is_customer_registered ) {
2068
  $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" );
2069
  $selected_action = isset( $_POST['mo2f_selected_action_free_plan'] ) ? $_POST['mo2f_selected_action_free_plan'] : $_POST['mo2f_selected_action_standard_plan'];
2070
  $user_phone = '';
 
2071
  if ( isset( $_SESSION['user_phone'] ) ) {
2072
  $user_phone = $_SESSION['user_phone'] != 'false' ? $_SESSION['user_phone'] : $Mo2fdbQueries->get_user_detail( 'mo2f_user_phone', $user->ID );
2073
  }
2083
  $Mo2fdbQueries->update_user_details( $user->ID, array( 'mo2f_configured_2FA_method' => $selected_2FA_method ) );
2084
 
2085
  // update the server
2086
+ if(!MO2F_IS_ONPREM)
2087
+ $this->mo2f_save_2_factor_method( $user, $selected_2FA_method );
2088
  if ( in_array( $selected_2FA_method, array(
2089
+ "miniOrange QR Code Authentication",
2090
  "miniOrange Soft Token",
2091
+ "miniOrange Push Notification",
2092
+ "Google Authenticator",
2093
+ "Security Questions",
2094
+ "Authy Authenticator",
2095
+ "Email Verification",
2096
+ "OTP Over SMS",
2097
+ "OTP Over Email",
2098
+ "OTP Over SMS and Email",
2099
+ "Hardware Token"
2100
  ) ) ) {
2101
 
2102
  } else {
2104
  }
2105
 
2106
  }
 
2107
  } else if ( $selected_action == "configure2factor" ) {
2108
 
2109
  //show configuration form of respective Two Factor method
2110
  update_user_meta( $user->ID, 'configure_2FA', 1 );
2111
  update_user_meta( $user->ID, 'mo2f_2FA_method_to_configure', $selected_2FA_method );
 
2112
  }
2113
 
2114
  } else {
2169
  } else {
2170
  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 );
2171
  }
2172
+ }
2173
+
2174
+ else if ( isset( $_POST['option'] ) && $_POST['option'] == 'mo_2factor_test_authentication_method' ) {
2175
  //network security feature
2176
  $nonce = $_POST['mo_2factor_test_authentication_method_nonce'];
2177
 
2192
  $api_key = get_option( 'mo2f_api_key' );
2193
 
2194
  if ( $selected_2FA_method == 'Security Questions' ) {
2195
+
2196
+ if(MO2F_IS_ONPREM){
2197
+ $question_answers = get_user_meta($user->ID , 'mo2f_kba_challenge');
2198
+ $challenge_questions = array_keys($question_answers[0]);
2199
+ $random_keys = array_rand($challenge_questions,2);
2200
+ $challenge_ques1 = $challenge_questions[$random_keys[0]];
2201
+ $challenge_ques2 = $challenge_questions[$random_keys[1]];
2202
+ $questions = array($challenge_ques1,$challenge_ques2);
2203
+ update_user_meta( $user->ID, 'kba_questions_user', $questions );
2204
+ } else{
2205
+ $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
2206
  if ( json_last_error() == JSON_ERROR_NONE ) { /* Generate KBA Questions*/
2207
  if ( $response['status'] == 'SUCCESS' ) {
2208
  $_SESSION['mo2f_transactionId'] = $response['txId'];
2226
  $this->mo_auth_show_error_message();
2227
 
2228
  }
2229
+ }
2230
 
2231
  } else if ( $selected_2FA_method == 'miniOrange Push Notification' ) {
2232
  $response = json_decode( $customer->send_otp_token( $email, $selected_2FA_method_server, $customer_key, $api_key ), true );
2457
  $enduser = new Two_Factor_Setup();
2458
  $enduser->mo2f_update_userinfo( $email, 'OUT OF BAND EMAIL', null, 'API_2FA', true );
2459
 
2460
+ update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ACCOUNT_RETRIEVED_SUCCESSFULLY" ) . ' <b>' . Mo2fConstants:: langTranslate( "EMAIL_VERFI" ) . '</b> ' . Mo2fConstants:: langTranslate( "DEFAULT_2ND_FACTOR" ) . ' <a href=\"admin.php?page=miniOrange_2_factor_settings&amp;mo2f_tab=mobile_configure\" >' . Mo2fConstants:: langTranslate( "CLICK_HERE" ) . '</a> ' . Mo2fConstants:: langTranslate( "CONFIGURE_2FA" ) );
2461
  $this->mo_auth_show_success_message();
2462
  } else {
2463
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "ERROR_CREATE_ACC_OTP" ) );
2697
  }
2698
 
2699
  function miniorange_email_verification_call( $current_user ) {
2700
+ if(MO2F_IS_ONPREM)
2701
+ {
2702
+ global $Mo2fdbQueries;
2703
+ $challengeMobile = new Customer_Setup();
2704
+ $email = get_user_meta($current_user->ID,'email',true);
2705
+ $is_flow_driven_setup = ! ( get_user_meta( $current_user->ID, 'current_modal', true ) ) ? 0 : 1;
2706
+
2707
+ $subject = '2-Factor Authentication(Email verification)';
2708
+ $headers = array('Content-Type: text/html; charset=UTF-8');
2709
+ $txid = '';
2710
+ $otpToken = '';
2711
+ $otpTokenD = '';
2712
+ for($i=1;$i<7;$i++)
2713
+ {
2714
+ $otpToken .= rand(0,9);
2715
+ $txid .= rand(100,999);
2716
+ $otpTokenD .= rand(0,9);
2717
+ }
2718
+ $otpTokenH = hash('sha512',$otpToken);
2719
+ $otpTokenDH = hash('sha512', $otpTokenD);
2720
+ $_SESSION['txid'] = $txid;
2721
+ $_SESSION['otpToken'] = $otpToken;
2722
+ $userID = hash('sha512',$current_user->ID);
2723
+ //update_site_option('otpTokenEmailV',$otpTokenH);
2724
+ update_site_option($userID,$otpTokenH);
2725
+ update_site_option($txid,3);
2726
+ $userIDd = $userID . 'D';
2727
+ update_site_option($userIDd,$otpTokenDH);
2728
+ $url = get_site_option('siteurl').'/wp-login.php?';
2729
+ $message = '<table cellpadding="25" style="margin:0px auto">
2730
+ <tbody>
2731
+ <tr>
2732
+ <td>
2733
+ <table cellpadding="24" width="584px" style="margin:0 auto;max-width:584px;background-color:#f6f4f4;border:1px solid #a8adad">
2734
+ <tbody>
2735
+ <tr>
2736
+ <td><img src="https://ci5.googleusercontent.com/proxy/10EQeM1udyBOkfD2dwxGhIaMXV4lOwCRtUecpsDkZISL0JIkOL2JhaYhVp54q6Sk656rW2rpAFJFEgGQiAOVcYIIKxXYMHHMNSNB=s0-d-e1-ft#https://login.xecurify.com/moas/images/xecurify-logo.png" style="color:#5fb336;text-decoration:none;display:block;width:auto;height:auto;max-height:35px" class="CToWUd"></td>
2737
+ </tr>
2738
+ </tbody>
2739
+ </table>
2740
+ <table cellpadding="24" style="background:#fff;border:1px solid #a8adad;width:584px;border-top:none;color:#4d4b48;font-family:Arial,Helvetica,sans-serif;font-size:13px;line-height:18px">
2741
+ <tbody>
2742
+ <tr>
2743
+ <td>
2744
+ <p style="margin-top:0;margin-bottom:20px">Dear Customers,</p>
2745
+ <p style="margin-top:0;margin-bottom:10px">You initiated a transaction <b>WordPress 2 Factor Authentication Plugin</b>:</p>
2746
+ <p style="margin-top:0;margin-bottom:10px">To accept, <a href="'.$url.'userID='.$userID.'&amp;accessToken='.$otpTokenH.'&amp;secondFactorAuthType=OUT+OF+BAND+EMAIL&amp;Txid='.$txid.'&amp;user='.$email.'" target="_blank" data-saferedirecturl="https://www.google.com/url?q=https://login.xecurify.com/moas/rest/validate-otp?customerKey%3D182589%26otpToken%3D735705%26secondFactorAuthType%3DOUT%2BOF%2BBAND%2BEMAIL%26user%3D'.$email.'&amp;source=gmail&amp;ust=1569905139580000&amp;usg=AFQjCNExKCcqZucdgRm9-0m360FdYAIioA">Accept Transaction</a></p>
2747
+ <p style="margin-top:0;margin-bottom:10px">To deny, <a href="'.$url.'userID='.$userID.'&amp;accessToken='.$otpTokenDH.'&amp;secondFactorAuthType=OUT+OF+BAND+EMAIL&amp;Txid='.$txid.'&amp;user='.$email.'" target="_blank" data-saferedirecturl="https://www.google.com/url?q=https://login.xecurify.com/moas/rest/validate-otp?customerKey%3D182589%26otpToken%3D735705%26secondFactorAuthType%3DOUT%2BOF%2BBAND%2BEMAIL%26user%3D'.$email.'&amp;source=gmail&amp;ust=1569905139580000&amp;usg=AFQjCNExKCcqZucdgRm9-0m360FdYAIioA">Deny Transaction</a></p><div><div class="adm"><div id="q_31" class="ajR h4" data-tooltip="Hide expanded content" aria-label="Hide expanded content" aria-expanded="true"><div class="ajT"></div></div></div><div class="im">
2748
+ <p style="margin-top:0;margin-bottom:15px">Thank you,<br>miniOrange Team</p>
2749
+ <p style="margin-top:0;margin-bottom:0px;font-size:11px">Disclaimer: This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed.</p>
2750
+ </div></div></td>
2751
+ </tr>
2752
+ </tbody>
2753
+ </table>
2754
+ </td>
2755
+ </tr>
2756
+ </tbody>
2757
+ </table>';
2758
+ $result = wp_mail($email,$subject,$message,$headers);
2759
+ if($result){
2760
+ $time = "time".$txid;
2761
+ $currentTimeInMillis = round(microtime(true) * 1000);
2762
+ update_site_option($time,$currentTimeInMillis);
2763
+ update_site_option( 'mo2f_message', Mo2fConstants::langTranslate("VERIFICATION_EMAIL_SENT") .'<b> ' . $email . '</b>. ' . Mo2fConstants::langTranslate("ACCEPT_LINK_TO_VERIFY_EMAIL"));
2764
+ if ( ! $is_flow_driven_setup ) {
2765
+ update_user_meta($current_user->ID,'mo2f_configure_test_option','MO2F_TEST');
2766
+ $Mo2fdbQueries->update_user_details(
2767
+ $current_user->ID, array('mo2f_configured_2FA_method' => 'OUT OF BAND EMAIL',
2768
+ 'mo2f_2factor_enable_2fa_byusers' => 1) );
2769
+ $this->mo_auth_show_success_message();
2770
+ }
2771
+ }else{
2772
+ //unset($_SESSION[ 'mo2f_transactionId' ]);
2773
+ update_site_option( 'mo2f_message', Mo2fConstants::langTranslate("ERROR_DURING_PROCESS_EMAIL"));
2774
+ $this->mo_auth_show_error_message();
2775
+ }
2776
+
2777
+ }
2778
+ else
2779
+ {
2780
  global $Mo2fdbQueries;
2781
  $challengeMobile = new Customer_Setup();
2782
  $email = $Mo2fdbQueries->get_user_detail( 'mo2f_user_email', $current_user->ID );
2802
  update_option( 'mo2f_message', Mo2fConstants:: langTranslate( "INVALID_REQ" ) );
2803
  $this->mo_auth_show_error_message();
2804
  }
2805
+ }
2806
  }
2807
 
2808
  function mo_auth_activate() {
2854
  }
2855
  }
2856
  new Miniorange_Authentication;
2857
+ ?>
handler/twofa/two_fa_utility.php CHANGED
@@ -198,7 +198,6 @@ class MO2f_Utility {
198
  * @return string
199
  */
200
  public static function decrypt_data( $data, $key ) {
201
-
202
  $c = base64_decode($data);
203
  $ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
204
  $iv = substr($c, 0, $ivlen);
@@ -206,9 +205,13 @@ class MO2f_Utility {
206
  $ciphertext_raw = substr($c, $ivlen+$sha2len);
207
  $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
208
  $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
209
- if (hash_equals($hmac, $calcmac))//PHP 5.6+ timing attack safe comparison
 
210
  {
211
- $decrypted_text=$original_plaintext;
 
 
 
212
  }
213
 
214
  return $decrypted_text;
198
  * @return string
199
  */
200
  public static function decrypt_data( $data, $key ) {
 
201
  $c = base64_decode($data);
202
  $ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
203
  $iv = substr($c, 0, $ivlen);
205
  $ciphertext_raw = substr($c, $ivlen+$sha2len);
206
  $original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
207
  $calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
208
+ $decrypted_text = '';
209
+ if(is_string($hmac) and is_string($calcmac))
210
  {
211
+ if (hash_equals($hmac, $calcmac))//PHP 5.6+ timing attack safe comparison
212
+ {
213
+ $decrypted_text=$original_plaintext;
214
+ }
215
  }
216
 
217
  return $decrypted_text;
helper/constants.php CHANGED
@@ -11,7 +11,7 @@
11
  const ERR_403 = "403";
12
  const DEFAULT_CUSTOMER_KEY = "16555";
13
  const DEFAULT_API_KEY = "fFd2XcvTGDemZvbw1bcUesNJWEqKbbUq";
14
- const DB_VERSION = 148;
15
  const SUPPORT_EMAIL = 'info@xecurify.com';
16
  const IP_LOOKUP_TEMPLATE = '<span style="font-size:14px;font-weight:bold">GENERAL INFORMATION</span><table style="margin-left:2%;"><tr><td style="width:100px;">Response</td><td >:</td><td>{{status}}</td></tr><tr><td style="width:100px;">IP Address</td><td>:</td><td>{{ip}}</td></tr><tr><td>HostName</td><td>:</td><td>{{hostname}}</td></tr><tr><td>TimeZone</td><td>:</td><td>{{timezone}}</td></tr><tr><td>Time Difference</td><td>:</td><td>{{offset}}</td></tr></table><hr><span style="font-size:14px;font-weight:bold">LOCATION INFORMATION</span><table style="margin-left:2%;"><tr><td>Latitude</td><td>:</td><td>{{latitude}}</td></tr><tr><td>Longitude</td><td>:</td><td>{{longitude}}</td></tr><tr><td>Region</td><td>:</td><td>{{region}}</td></tr><tr><td>Country</td><td>:</td><td>{{country}}</td></tr><tr><td>City</td><td>:</td><td>{{city}}</td></tr><tr><td>Continent</td><td>:</td><td>{{continent}}</td></tr><tr><td>Curreny Code</td><td>:</td><td>{{curreny_code}}</td></tr><tr><td>Curreny Symbol</td><td>:</td><td>{{curreny_symbol}}</td></tr><tr><td>Per Dollar Value</td><td>:</td><td>{{per_dollar_value}}</td></tr></table>';
17
  const CURRENT_BROWSER = '<span style="font-size:10px;color:red;">( Current Browser )</span>';
@@ -37,6 +37,9 @@
37
  const IP_RANGE_BLOCKING = "IP Range Blocking";
38
  const FAILED_LOGIN_ATTEMPTS_FROM_NEW_IP = "Failed login attempts from new IP.";
39
  const LOGGED_IN_FROM_NEW_IP = "Logged in from new IP.";
 
 
 
40
  const PLUGIN = 'plugin';
41
  const THEMES = 'themes';
42
  const WPFILES = 'wpfiles';
@@ -80,14 +83,14 @@
80
 
81
  function define_global()
82
  {
83
- global $wpnsDbQueries,$moWpnsUtility,$dirName,$Mo2fdbQueries;
84
  $wpnsDbQueries = new MoWpnsDB();
85
  $moWpnsUtility = new MoWpnsUtility();
86
- $dirName = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR;
87
  $Mo2fdbQueries = new Mo2fDB();
88
  }
89
 
90
  }
91
  new MoWpnsConstants;
92
 
93
- ?>
11
  const ERR_403 = "403";
12
  const DEFAULT_CUSTOMER_KEY = "16555";
13
  const DEFAULT_API_KEY = "fFd2XcvTGDemZvbw1bcUesNJWEqKbbUq";
14
+ const DB_VERSION = 149;
15
  const SUPPORT_EMAIL = 'info@xecurify.com';
16
  const IP_LOOKUP_TEMPLATE = '<span style="font-size:14px;font-weight:bold">GENERAL INFORMATION</span><table style="margin-left:2%;"><tr><td style="width:100px;">Response</td><td >:</td><td>{{status}}</td></tr><tr><td style="width:100px;">IP Address</td><td>:</td><td>{{ip}}</td></tr><tr><td>HostName</td><td>:</td><td>{{hostname}}</td></tr><tr><td>TimeZone</td><td>:</td><td>{{timezone}}</td></tr><tr><td>Time Difference</td><td>:</td><td>{{offset}}</td></tr></table><hr><span style="font-size:14px;font-weight:bold">LOCATION INFORMATION</span><table style="margin-left:2%;"><tr><td>Latitude</td><td>:</td><td>{{latitude}}</td></tr><tr><td>Longitude</td><td>:</td><td>{{longitude}}</td></tr><tr><td>Region</td><td>:</td><td>{{region}}</td></tr><tr><td>Country</td><td>:</td><td>{{country}}</td></tr><tr><td>City</td><td>:</td><td>{{city}}</td></tr><tr><td>Continent</td><td>:</td><td>{{continent}}</td></tr><tr><td>Curreny Code</td><td>:</td><td>{{curreny_code}}</td></tr><tr><td>Curreny Symbol</td><td>:</td><td>{{curreny_symbol}}</td></tr><tr><td>Per Dollar Value</td><td>:</td><td>{{per_dollar_value}}</td></tr></table>';
17
  const CURRENT_BROWSER = '<span style="font-size:10px;color:red;">( Current Browser )</span>';
37
  const IP_RANGE_BLOCKING = "IP Range Blocking";
38
  const FAILED_LOGIN_ATTEMPTS_FROM_NEW_IP = "Failed login attempts from new IP.";
39
  const LOGGED_IN_FROM_NEW_IP = "Logged in from new IP.";
40
+ const ATTACK_LIMIT_EXCEEDED = "ale";
41
+ const RATE_LIMIT_EXCEEDED = "rle";
42
+ const RATE_LIMIT_EXCEEDED_CRAWLER_ATTACK= "rlecrawler";
43
  const PLUGIN = 'plugin';
44
  const THEMES = 'themes';
45
  const WPFILES = 'wpfiles';
83
 
84
  function define_global()
85
  {
86
+ global $wpnsDbQueries,$moWpnsUtility,$mo2f_dirName,$Mo2fdbQueries;
87
  $wpnsDbQueries = new MoWpnsDB();
88
  $moWpnsUtility = new MoWpnsUtility();
89
+ $mo2f_dirName = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR;
90
  $Mo2fdbQueries = new Mo2fDB();
91
  }
92
 
93
  }
94
  new MoWpnsConstants;
95
 
96
+ ?>
helper/curl.php CHANGED
@@ -76,8 +76,26 @@ class MocURL
76
  $response = self::callAPI($url, $json);
77
  return $response;
78
  }
79
-
80
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  function validate_recaptcha($ip,$response)
83
  {
@@ -94,7 +112,22 @@ class MocURL
94
  return $response;
95
  }
96
 
97
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
  function check_customer($email)
100
  {
@@ -109,6 +142,7 @@ class MocURL
109
 
110
  function mo_wpns_forgot_password()
111
  {
 
112
  $url = MoWpnsConstants::HOST_NAME . '/moas/rest/customer/password-reset';
113
  $email = get_option('mo2f_email');
114
  $customerKey = get_option('mo2f_customerKey');
@@ -139,8 +173,7 @@ class MocURL
139
  //added for feedback
140
 
141
  function send_email_alert($email,$phone,$message,$feedback_option){
142
-
143
- global $moWpnsUtility;
144
  global $user;
145
  $url = MoWpnsConstants::HOST_NAME . '/moas/api/notify/send';
146
  $customerKey = MoWpnsConstants::DEFAULT_CUSTOMER_KEY;
@@ -243,4 +276,4 @@ class MocURL
243
  curl_close($ch);
244
  return $content;
245
  }
246
- }
76
  $response = self::callAPI($url, $json);
77
  return $response;
78
  }
79
+ //CHECK
80
+ function send_otp_token($auth_type, $phone, $email)
81
+ {
82
+
83
+ $url = MoWpnsConstants::HOST_NAME . '/moas/api/auth/challenge';
84
+ $customerKey = MoWpnsConstants::DEFAULT_CUSTOMER_KEY;
85
+ $apiKey = MoWpnsConstants::DEFAULT_API_KEY;
86
+
87
+ $fields = array(
88
+ 'customerKey' => $customerKey,
89
+ 'email' => $email,
90
+ 'phone' => $phone,
91
+ 'authType' => $auth_type,
92
+ 'transactionName' => 'miniOrange 2-Factor'
93
+ );
94
+ $json = json_encode($fields);
95
+ $authHeader = $this->createAuthHeader($customerKey,$apiKey);
96
+ $response = self::callAPI($url, $json, $authHeader);
97
+ return $response;
98
+ }
99
 
100
  function validate_recaptcha($ip,$response)
101
  {
112
  return $response;
113
  }
114
 
115
+ function validate_otp_token($transactionId,$otpToken)
116
+ {
117
+ $url = MoWpnsConstants::HOST_NAME . '/moas/api/auth/validate';
118
+ $customerKey = MoWpnsConstants::DEFAULT_CUSTOMER_KEY;
119
+ $apiKey = MoWpnsConstants::DEFAULT_API_KEY;
120
+
121
+ $fields = array(
122
+ 'txId' => $transactionId,
123
+ 'token' => $otpToken,
124
+ );
125
+
126
+ $json = json_encode($fields);
127
+ $authHeader = $this->createAuthHeader($customerKey,$apiKey);
128
+ $response = self::callAPI($url, $json, $authHeader);
129
+ return $response;
130
+ }
131
 
132
  function check_customer($email)
133
  {
142
 
143
  function mo_wpns_forgot_password()
144
  {
145
+
146
  $url = MoWpnsConstants::HOST_NAME . '/moas/rest/customer/password-reset';
147
  $email = get_option('mo2f_email');
148
  $customerKey = get_option('mo2f_customerKey');
173
  //added for feedback
174
 
175
  function send_email_alert($email,$phone,$message,$feedback_option){
176
+ global $moWpnsUtility;
 
177
  global $user;
178
  $url = MoWpnsConstants::HOST_NAME . '/moas/api/notify/send';
179
  $customerKey = MoWpnsConstants::DEFAULT_CUSTOMER_KEY;
276
  curl_close($ch);
277
  return $content;
278
  }
279
+ }
helper/dashboard_security_notification.php CHANGED
@@ -9,8 +9,20 @@ class miniorange_security_notification{
9
  wp_add_dashboard_widget('custom_help_widget', 'MiniOrange Website Security',array($this, 'custom_dashboard_help'));
10
  }
11
 
12
- function custom_dashboard_help() {
13
- global $wpdb,$type_of_scan,$total_scanned_files,$wpnsDbQueries;
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  $array = $wpdb->get_results("SELECT MAX(id) as id FROM ".$wpdb->base_prefix.'wpns_malware_scan_report');
16
 
@@ -50,7 +62,8 @@ class miniorange_security_notification{
50
  }
51
 
52
 
53
-
 
54
 
55
  echo "<html>
56
  <head>
@@ -65,7 +78,7 @@ class miniorange_security_notification{
65
 
66
  <div style='width:100%;background-color:#555f5f;padding-top:10px;''>
67
  <div style='font-size:25px;color:white;text-align:center'>
68
- <strong style='font-weight:300;''>Last Scan Result <span style='color:orange;'>[". $type_of_scan." ]</span></strong>
69
  </div>
70
  <hr>
71
  <div>
@@ -107,7 +120,52 @@ class miniorange_security_notification{
107
  ";
108
 
109
  echo '<a class="button button-primary" style="background-color:#f0a702;width:100%;text-align:center;" href="admin.php?page=mo_2fa_malwarescan&tab=default&view='.$latest_id.'"><h3 style="background-color:#f0a702">View Details</h3></a>';
110
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  echo '<br><br>';
112
 
113
  echo "<div style='width:100%;background-color:#555f5f;padding-top:10px;'>
@@ -151,19 +209,19 @@ class miniorange_security_notification{
151
  </tbody>
152
  </table>
153
  </div>
 
154
  <a class='button button-primary' style='background-color:#f0a702;width:100%;text-align:center' href='admin.php?page=mo_2fa_backup'><h3 style='background-color:#f0a702'>Take Backup</h3></a>
155
  </div>";
156
 
157
 
158
 
159
 
160
- }
161
 
162
 
163
 
164
  }
165
 
166
-
167
-
168
 
169
  ?>
9
  wp_add_dashboard_widget('custom_help_widget', 'MiniOrange Website Security',array($this, 'custom_dashboard_help'));
10
  }
11
 
12
+ function custom_dashboard_help() {
13
+ global $wpdb,$type_of_scan,$total_scanned_files, $wpnsDbQueries;
14
+
15
+
16
+
17
+ $fake_domains = get_site_option('number_of_fake_reg');
18
+ if($fake_domains == false){
19
+ $fake_domains = 0;
20
+ }
21
+ $failed_transaction = $wpnsDbQueries->get_count_of_attacks_blocked();
22
+ $weakPass = get_site_option('users_with_weak_pass');
23
+ if($weakPass == false){
24
+ $weakPass = 0;
25
+ }
26
 
27
  $array = $wpdb->get_results("SELECT MAX(id) as id FROM ".$wpdb->base_prefix.'wpns_malware_scan_report');
28
 
62
  }
63
 
64
 
65
+ if(current_user_can('administrator'))
66
+ {
67
 
68
  echo "<html>
69
  <head>
78
 
79
  <div style='width:100%;background-color:#555f5f;padding-top:10px;''>
80
  <div style='font-size:25px;color:white;text-align:center'>
81
+ <strong style='font-weight:300;''>Last Scan Result <span style='color:orange;'>[". $type_of_scan."]</span></strong>
82
  </div>
83
  <hr>
84
  <div>
120
  ";
121
 
122
  echo '<a class="button button-primary" style="background-color:#f0a702;width:100%;text-align:center;" href="admin.php?page=mo_2fa_malwarescan&tab=default&view='.$latest_id.'"><h3 style="background-color:#f0a702">View Details</h3></a>';
123
+
124
+ echo "<br><br><br>";
125
+
126
+ echo "<div style='width:100%;background-color:#555f5f;padding-top:10px;'>
127
+ <div style='font-size:25px;color:white;text-align:center'>
128
+ <strong style='font-weight:300;'>Login and Spam<span style='color:orange;'>[ On your Website ]</span></strong>
129
+ </div>
130
+ <div>
131
+ <table>
132
+ <tbody>
133
+
134
+ <tr>
135
+ <td style='border-collapse:collapse!important;color:#0a0a0a;line-height:1.3;margin:0;padding:0;text-align:left;vertical-align:top;word-wrap:normal'>
136
+ <table dir='ltr' style='table-layout:fixed;margin:10px 0 20px 0;padding:0;vertical-align:top;width:100%'>
137
+ <tbody>
138
+ <tr>
139
+ <td style='text-align:center;font-size:36px;color:#ffffff;font-weight:400' ><strong>".$failed_transaction."</strong></td>
140
+ <td style='text-align:center;font-size:36px;color:#ffffff;font-weight:400'><strong>".$weakPass."</strong></td>
141
+ <td style='text-align:center;font-size:36px;color:#ffffff;font-weight:400'><strong>".$fake_domains."</strong></td>
142
+
143
+
144
+ </tr>
145
+
146
+ <tr>
147
+ <td>&nbsp;
148
+ </td>
149
+ <td>
150
+ </td>
151
+ </tr>
152
+ <tr>
153
+ <td style='font-size:18px;color:#ffffff;text-align:center'><strong style='font-weight:300;'>Login Attempts Failed</strong></td>
154
+ <td style='font-size:18px;color:#ffffff;text-align:center'><strong style='font-weight:300;'>Users with weak passwords</strong></td>
155
+ <td style='font-size:18px;color:#ffffff;text-align:center'><strong style='font-weight:300;'>Fake Domain Registerations</strong></td>
156
+
157
+
158
+ </tr>
159
+ </tbody>
160
+ </table>
161
+
162
+ </tr>
163
+ </tbody>
164
+ </table>
165
+ </div>
166
+ <a class='button button-primary' style='background-color:#f0a702;width:100%;text-align:center' href='admin.php?page=mo_2fa_login_and_spam&tab=default&view==".$latest_id."'><h3 style='background-color:#f0a702'>View Details</h3></a>
167
+ </div>";
168
+
169
  echo '<br><br>';
170
 
171
  echo "<div style='width:100%;background-color:#555f5f;padding-top:10px;'>
209
  </tbody>
210
  </table>
211
  </div>
212
+
213
  <a class='button button-primary' style='background-color:#f0a702;width:100%;text-align:center' href='admin.php?page=mo_2fa_backup'><h3 style='background-color:#f0a702'>Take Backup</h3></a>
214
  </div>";
215
 
216
 
217
 
218
 
219
+ }
220
 
221
 
222
 
223
  }
224
 
225
+ }
 
226
 
227
  ?>
helper/messages.php CHANGED
@@ -3,7 +3,8 @@
3
  class MoWpnsMessages
4
  {
5
  // ip-blocking messages
6
- const INVALID_IP = "Please enter a valid IP address.";
 
7
  const IP_ALREADY_BLOCKED = "IP Address is already Blocked";
8
  const IP_PERMANENTLY_BLOCKED = "IP Address is blocked permanently.";
9
  const IP_ALREADY_WHITELISTED = "IP Address is already Whitelisted.";
@@ -32,6 +33,9 @@
32
  const NOTIFY_ON_UNUSUAL_ACTIVITY = "Email notification is enabled for user for unusual activities.";
33
  const DONOT_NOTIFY_ON_UNUSUAL_ACTIVITY = "Email notification is disabled for user for unusual activities.";
34
  const NONCE_ERROR = "Nonce Error.";
 
 
 
35
 
36
  //registration security
37
  const DOMAIN_BLOCKING_ENABLED = "Blocking fake user registrations is Enabled.";
@@ -60,6 +64,8 @@
60
  const SUPPORT_FORM_VALUES = "Please submit your query along with email.";
61
  const SUPPORT_FORM_SENT = "Thanks for getting in touch! We shall get back to you shortly.";
62
  const SUPPORT_FORM_ERROR = "Your query could not be submitted. Please try again.";
 
 
63
  //feedback Form
64
  const DEACTIVATE_PLUGIN = "Plugin deactivated successfully";
65
 
@@ -105,6 +111,8 @@
105
  const LOGIN_DISABLE = 'Login security and spam protection features are disabled.';
106
  const BACKUP_ENABLE = 'Encrypted backup features are available. Configure it in the Encrypted Backup tab.';
107
  const BACKUP_DISABLE = 'Encrypted Backup features are disabled.';
 
 
108
  const MALWARE_ENABLE = 'Malware scan features and modes are available. Configure it in the Malware Scan tab.';
109
  const MALWARE_DISABLE = 'Malware scan features are disabled.';
110
  const ADV_BLOCK_ENABLE = 'Advanced blocking features are available. Configure it in the Advanced blocking tab.';
3
  class MoWpnsMessages
4
  {
5
  // ip-blocking messages
6
+ const INVALID_IP = "The IP address you entered is not valid or the IP Range is not valid.";
7
+ const INVALID_RANGE = "IP Range is not valid, please enter a valid range";
8
  const IP_ALREADY_BLOCKED = "IP Address is already Blocked";
9
  const IP_PERMANENTLY_BLOCKED = "IP Address is blocked permanently.";
10
  const IP_ALREADY_WHITELISTED = "IP Address is already Whitelisted.";
33
  const NOTIFY_ON_UNUSUAL_ACTIVITY = "Email notification is enabled for user for unusual activities.";
34
  const DONOT_NOTIFY_ON_UNUSUAL_ACTIVITY = "Email notification is disabled for user for unusual activities.";
35
  const NONCE_ERROR = "Nonce Error.";
36
+ const TWO_FA_ON_LOGIN_PROMPT_ENABLED = "2FA prompt on the WP Login Page Enabled.";
37
+ const TWO_FA_ON_LOGIN_PROMPT_DISABLED = "2FA prompt on the WP Login Page Disabled.";
38
+ const TWO_FA_PROMPT_LOGIN_PAGE = 'Please disable Login with 2nd facor only to enable 2FA prompt on login page.';
39
 
40
  //registration security
41
  const DOMAIN_BLOCKING_ENABLED = "Blocking fake user registrations is Enabled.";
64
  const SUPPORT_FORM_VALUES = "Please submit your query along with email.";
65
  const SUPPORT_FORM_SENT = "Thanks for getting in touch! We shall get back to you shortly.";
66
  const SUPPORT_FORM_ERROR = "Your query could not be submitted. Please try again.";
67
+ // request demo form
68
+ const DEMO_FORM_ERROR = "Please fill out all the fields.";
69
  //feedback Form
70
  const DEACTIVATE_PLUGIN = "Plugin deactivated successfully";
71
 
111
  const LOGIN_DISABLE = 'Login security and spam protection features are disabled.';
112
  const BACKUP_ENABLE = 'Encrypted backup features are available. Configure it in the Encrypted Backup tab.';
113
  const BACKUP_DISABLE = 'Encrypted Backup features are disabled.';
114
+ const DELETE_FILE = 'Someone has deleted the backup by going to directory please refreash the page';
115
+ const NOT_ADMIN = 'You are not a admin. Only admin can download';
116
  const MALWARE_ENABLE = 'Malware scan features and modes are available. Configure it in the Malware Scan tab.';
117
  const MALWARE_DISABLE = 'Malware scan features are disabled.';
118
  const ADV_BLOCK_ENABLE = 'Advanced blocking features are available. Configure it in the Advanced blocking tab.';
helper/pluginUtility.php CHANGED
@@ -462,8 +462,10 @@ class MoWpnsHandler
462
 
463
 
464
  function is_country_blocked($userIp)
465
- {
 
466
  $countrycodes = get_option('mo_wpns_countrycodes');
 
467
  if($countrycodes && !empty($countrycodes)){
468
  $ip_data = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=".$userIp));
469
  if($ip_data && $ip_data->geoplugin_countryName != null){
462
 
463
 
464
  function is_country_blocked($userIp)
465
+ {
466
+
467
  $countrycodes = get_option('mo_wpns_countrycodes');
468
+
469
  if($countrycodes && !empty($countrycodes)){
470
  $ip_data = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=".$userIp));
471
  if($ip_data && $ip_data->geoplugin_countryName != null){
helper/plugins.php CHANGED
@@ -30,7 +30,7 @@
30
 
31
  if(!get_option( 'mo2f_customerKey') || !get_option( 'mo2f_api_key') || !get_option( 'mo2f_customer_token') || !get_option( 'mo2f_app_secret'))
32
  {
33
- global $dirName;
34
  $current_user = wp_get_current_user();
35
  $mo2fa = new Two_Factor_Setup();
36
  update_option( 'mo2f_email' ,get_option( 'mo2f_email'));
30
 
31
  if(!get_option( 'mo2f_customerKey') || !get_option( 'mo2f_api_key') || !get_option( 'mo2f_customer_token') || !get_option( 'mo2f_app_secret'))
32
  {
33
+ global $mo2f_dirName;
34
  $current_user = wp_get_current_user();
35
  $mo2fa = new Two_Factor_Setup();
36
  update_option( 'mo2f_email' ,get_option( 'mo2f_email'));
helper/utility.php CHANGED
@@ -196,7 +196,10 @@ class MoWpnsUtility
196
 
197
  // $mocURL = new MocURL();
198
  // return $mocURL->send_notification($toEmail,$subject,$content,$fromEmail,get_bloginfo(),$username);
199
- return $this->wp_mail_send_notification($toEmail,$subject,$content,$fromEmail);
 
 
 
200
  }
201
 
202
  //Check if null what will be the message
@@ -210,6 +213,18 @@ class MoWpnsUtility
210
  case MoWpnsConstants::IP_RANGE_BLOCKING:
211
  $content = "Hello,<br><br>The user's IP Address <b>".$ipAddress."</b> was found in IP Range specified by you in Advanced IP Blocking and we have blocked his IP address for further access to your website <b>".get_bloginfo()."</b>.<br><br>You can login to your WordPress dashaboard to check more details.<br><br>Thanks,<br>miniOrange" ;
212
  return $content;
 
 
 
 
 
 
 
 
 
 
 
 
213
  case MoWpnsConstants::LOGGED_IN_FROM_NEW_IP:
214
  $content = "Hello ".$username.",<br><br>Your account was logged in from new IP Address <b>".$ipAddress."</b> on website <b>".get_bloginfo()."</b>. Please <a href='mailto:".$fromEmail."'>contact us</a> if you don't recognise this activity.<br><br>Thanks,<br>".get_bloginfo() ;
215
  return $content;
@@ -258,8 +273,7 @@ class MoWpnsUtility
258
  else if(strpos($useragent, 'safari') !== false)
259
  return 'safari';
260
  }
261
- //to know if the features are being used or not.
262
-
263
  public static function getFeatureStatus(){
264
  $status='';
265
  $status.="#";
@@ -282,7 +296,6 @@ class MoWpnsUtility
282
  $status.="R".rand(0,1000);
283
  return $status;
284
  }
285
- //check if two factor is used for security
286
  function checkPlugins(){
287
  $installed="";
288
  $filedirname=dirname(dirname(dirname(__FILE__)));
196
 
197
  // $mocURL = new MocURL();
198
  // return $mocURL->send_notification($toEmail,$subject,$content,$fromEmail,get_bloginfo(),$username);
199
+
200
+ $mo_wpns_config->audit_email_notification_sent_to_user($username,$ipAddress,$reason);
201
+ $status = $this->wp_mail_send_notification($toEmail,$subject,$content,$fromEmail);
202
+ return $status;
203
  }
204
 
205
  //Check if null what will be the message
213
  case MoWpnsConstants::IP_RANGE_BLOCKING:
214
  $content = "Hello,<br><br>The user's IP Address <b>".$ipAddress."</b> was found in IP Range specified by you in Advanced IP Blocking and we have blocked his IP address for further access to your website <b>".get_bloginfo()."</b>.<br><br>You can login to your WordPress dashaboard to check more details.<br><br>Thanks,<br>miniOrange" ;
215
  return $content;
216
+ case MoWpnsConstants::BLOCKED_BY_ADMIN:
217
+ $content = "Hello,<br><br>The user with IP Address <b>".$ipAddress."</b> has blocked by admin and we have blocked his IP address for further access to website.<br><br>You can login to your WordPress dashaboard to check more details.<br><br>Thanks,<br>miniOrange" ;
218
+ return $content;
219
+ case MoWpnsConstants::ATTACK_LIMIT_EXCEEDED:
220
+ $content = "Hello,<br><br>The user with IP Address <b>".$ipAddress."</b> has attack limit exceed on your website <b>".get_bloginfo()."</b> and we have blocked his IP address for further access to website.<br><br>You can login to your WordPress dashaboard to check more details.<br><br>Thanks,<br>miniOrange";
221
+ return $content;
222
+ case MoWpnsConstants::RATE_LIMIT_EXCEEDED:
223
+ $content = "Hello,<br><br>The user with IP Address <b>".$ipAddress."</b> has rate limit exceed on your website <b>".get_bloginfo()."</b> and we have blocked his IP address for further access to website.<br><br>You can login to your WordPress dashaboard to check more details.<br><br>Thanks,<br>miniOrange";
224
+ return $content;
225
+ case MoWpnsConstants::RATE_LIMIT_EXCEEDED_CRAWLER_ATTACK:
226
+ $content = "Hello,<br><br>The user with IP Address <b>".$ipAddress."</b> has found as a crawler on your website <b>".get_bloginfo()."</b> and we have blocked his IP address for further access to website.<br><br>You can login to your WordPress dashaboard to check more details.<br><br>Thanks,<br>miniOrange";
227
+ return $content;
228
  case MoWpnsConstants::LOGGED_IN_FROM_NEW_IP:
229
  $content = "Hello ".$username.",<br><br>Your account was logged in from new IP Address <b>".$ipAddress."</b> on website <b>".get_bloginfo()."</b>. Please <a href='mailto:".$fromEmail."'>contact us</a> if you don't recognise this activity.<br><br>Thanks,<br>".get_bloginfo() ;
230
  return $content;
273
  else if(strpos($useragent, 'safari') !== false)
274
  return 'safari';
275
  }
276
+
 
277
  public static function getFeatureStatus(){
278
  $status='';
279
  $status.="#";
296
  $status.="R".rand(0,1000);
297
  return $status;
298
  }
 
299
  function checkPlugins(){
300
  $installed="";
301
  $filedirname=dirname(dirname(dirname(__FILE__)));
includes/css/bootstrap.min.css ADDED
@@ -0,0 +1,1875 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .mo2f_carousel {
2
+ position: relative;
3
+ padding-bottom: 18px !important;
4
+
5
+ }
6
+
7
+ .mo2f_carousel-inner {
8
+ position: relative;
9
+ width: 100%;
10
+ overflow: hidden;
11
+
12
+ }
13
+
14
+ .mo2f_carousel-inner > .item {
15
+ position: relative;
16
+ display: none;
17
+ -webkit-transition: .6s ease-in-out left;
18
+ -o-transition: .6s ease-in-out left;
19
+ transition: .6s ease-in-out left;
20
+ height: 300px !important;
21
+
22
+ }
23
+
24
+ .mo2f_carousel-inner > .item > img, .mo2f_carousel-inner > .item > a > img {
25
+ line-height: 1;
26
+
27
+ max-height: 300px !important;
28
+ max-width: 600px !important;
29
+ }
30
+
31
+ @media all and (transform-3d) , ( -webkit-transform-3d ) {
32
+ .mo2f_carousel-inner > .item {
33
+ -webkit-transition: -webkit-transform .6s ease-in-out;
34
+ -o-transition: -o-transform .6s ease-in-out;
35
+ transition: transform .6s ease-in-out;
36
+ -webkit-backface-visibility: hidden;
37
+ backface-visibility: hidden;
38
+ -webkit-perspective: 1000;
39
+ perspective: 1000
40
+ }
41
+
42
+ .mo2f_carousel-inner > .item.next, .mo2f_carousel-inner > .item.active.right {
43
+ left: 0;
44
+ -webkit-transform: translate3d(100%, 0, 0);
45
+ transform: translate3d(100%, 0, 0)
46
+ }
47
+
48
+ .mo2f_carousel-inner > .item.prev, .mo2f_carousel-inner > .item.active.left {
49
+ left: 0;
50
+ -webkit-transform: translate3d(-100%, 0, 0);
51
+ transform: translate3d(-100%, 0, 0)
52
+ }
53
+
54
+ .mo2f_carousel-inner > .item.next.left, .mo2f_carousel-inner > .item.prev.right, .mo2f_carousel-inner > .item.active {
55
+ left: 0;
56
+ -webkit-transform: translate3d(0, 0, 0);
57
+ transform: translate3d(0, 0, 0)
58
+ }
59
+ }
60
+
61
+ .mo2f_carousel-inner > .active, .mo2f_carousel-inner > .next, .mo2f_carousel-inner > .prev {
62
+ display: block
63
+ }
64
+
65
+ .mo2f_carousel-inner > .active {
66
+ left: 0
67
+ }
68
+
69
+ .mo2f_carousel-inner > .next, .mo2f_carousel-inner > .prev {
70
+ position: absolute;
71
+ top: 0;
72
+ width: 100%
73
+ }
74
+
75
+ .mo2f_carousel-inner > .next {
76
+ left: 100%
77
+ }
78
+
79
+ .mo2f_carousel-inner > .prev {
80
+ left: -100%
81
+ }
82
+
83
+ .mo2f_carousel-inner > .next.left, .mo2f_carousel-inner > .prev.right {
84
+ left: 0
85
+ }
86
+
87
+ .mo2f_carousel-inner > .active.left {
88
+ left: -100%
89
+ }
90
+
91
+ .mo2f_carousel-inner > .active.right {
92
+ left: 100%
93
+ }
94
+
95
+ .mo2f_carousel-control {
96
+ position: absolute;
97
+ top: 0;
98
+ bottom: 0;
99
+ left: 0;
100
+ width: 15%;
101
+ font-size: 20px;
102
+ color: #fff;
103
+ text-align: center;
104
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
105
+ filter: alpha(opacity=50);
106
+ opacity: .5
107
+ }
108
+
109
+ .mo2f_carousel-control.left {
110
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0,
111
+ rgba(0, 0, 0, .0001) 100%);
112
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0,
113
+ rgba(0, 0, 0, .0001) 100%);
114
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)),
115
+ to(rgba(0, 0, 0, .0001)));
116
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0,
117
+ rgba(0, 0, 0, .0001) 100%);
118
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000',
119
+ endColorstr='#00000000', GradientType=1);
120
+ background-repeat: repeat-x
121
+ }
122
+
123
+ .mo2f_carousel-control.right {
124
+ right: 0;
125
+ left: auto;
126
+ background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0,
127
+ rgba(0, 0, 0, .5) 100%);
128
+ background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0,
129
+ rgba(0, 0, 0, .5) 100%);
130
+ background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)),
131
+ to(rgba(0, 0, 0, .5)));
132
+ background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0,
133
+ rgba(0, 0, 0, .5) 100%);
134
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000',
135
+ endColorstr='#80000000', GradientType=1);
136
+ background-repeat: repeat-x
137
+ }
138
+
139
+ .mo2f_carousel-control:hover, .mo2f_carousel-control:focus {
140
+ color: #fff;
141
+ text-decoration: none;
142
+ filter: alpha(opacity=90);
143
+ outline: 0;
144
+ opacity: .9
145
+ }
146
+
147
+ .mo2f_carousel-control .icon-prev, .mo2f_carousel-control .icon-next, .mo2f_carousel-control .glyphicon-chevron-left, .mo2f_carousel-control .glyphicon-chevron-right {
148
+ position: absolute;
149
+ top: 50%;
150
+ z-index: 5;
151
+ display: inline-block
152
+ }
153
+
154
+ .mo2f_carousel-control .icon-prev, .mo2f_carousel-control .glyphicon-chevron-left {
155
+ left: 50%;
156
+ margin-left: -10px
157
+ }
158
+
159
+ .mo2f_carousel-control .icon-next, .mo2f_carousel-control .glyphicon-chevron-right {
160
+ right: 50%;
161
+ margin-right: -10px
162
+ }
163
+
164
+ .mo2f_carousel-control .icon-prev, .mo2f_carousel-control .icon-next {
165
+ width: 20px;
166
+ height: 20px;
167
+ margin-top: -10px;
168
+ font-family: serif
169
+ }
170
+
171
+ .mo2f_carousel-control .icon-prev:before {
172
+ content: '\2039'
173
+ }
174
+
175
+ .mo2f_carousel-control .icon-next:before {
176
+ content: '\203a'
177
+ }
178
+
179
+ .mo2f_carousel-indicators {
180
+ position: absolute;
181
+ bottom: -25px;
182
+ left: 50%;
183
+ z-index: 15;
184
+ width: 60%;
185
+ padding-left: 0;
186
+ margin-left: -30%;
187
+ text-align: center;
188
+ list-style: none
189
+ }
190
+
191
+ .mo2f_carousel-indicators li {
192
+ display: inline-block;
193
+ width: 10px;
194
+ height: 10px;
195
+ margin: 1px;
196
+ text-indent: -999px;
197
+ cursor: pointer;
198
+ background-color: #0 \9;
199
+ background-color: rgba(0, 0, 0, 0);
200
+ border: 1px solid #0073aa;
201
+ border-radius: 10px
202
+ }
203
+
204
+ .mo2f_carousel-indicators .active {
205
+ width: 12px;
206
+ height: 12px;
207
+ margin: 0;
208
+ background-color: #0073aa;
209
+ }
210
+
211
+ .mo2f_carousel-caption {
212
+ position: absolute;
213
+ right: 15%;
214
+ bottom: 20px;
215
+ left: 15%;
216
+ z-index: 10;
217
+ padding-top: 20px;
218
+ padding-bottom: 20px;
219
+ color: #fff;
220
+ text-align: center;
221
+ text-shadow: 0 1px 2px rgba(0, 0, 0, .6)
222
+ }
223
+
224
+ .mo2f_carousel-caption .btn {
225
+ text-shadow: none
226
+ }
227
+
228
+ @media screen and (min-width: 768px) {
229
+ .mo2f_carousel-control .glyphicon-chevron-left, .mo2f_carousel-control .glyphicon-chevron-right, .mo2f_carousel-control .icon-prev, .mo2f_carousel-control .icon-next {
230
+ width: 30px;
231
+ height: 30px;
232
+ margin-top: -15px;
233
+ font-size: 30px
234
+ }
235
+
236
+ .mo2f_carousel-control .glyphicon-chevron-left, .mo2f_carousel-control .icon-prev {
237
+ margin-left: -15px
238
+ }
239
+
240
+ .mo2f_carousel-control .glyphicon-chevron-right, .mo2f_carousel-control .icon-next {
241
+ margin-right: -15px
242
+ }
243
+
244
+ .mo2f_carousel-caption {
245
+ right: 20%;
246
+ left: 20%;
247
+ padding-bottom: 30px
248
+ }
249
+
250
+ .mo2f_carousel-indicators {
251
+ bottom: -14px
252
+ }
253
+ }
254
+
255
+ .hidden {
256
+ display: none;
257
+ }
258
+
259
+ .float-right {
260
+ text-align: right;
261
+ }
262
+
263
+ .mo2f_collapse {
264
+ display: none;
265
+ / / visibility: hidden;
266
+ font-size: 14px !important;
267
+
268
+ }
269
+
270
+ .mo2f_collapse.in {
271
+ display: block;
272
+ visibility: visible;
273
+
274
+ }
275
+
276
+ .mo2f_collapsing {
277
+ position: relative;
278
+ font-size: 14px !important;
279
+ height: 0;
280
+ overflow: hidden;
281
+ -webkit-transition-timing-function: ease;
282
+ -o-transition-timing-function: ease;
283
+ transition-timing-function: ease;
284
+ -webkit-transition-duration: .20s;
285
+ -o-transition-duration: .20s;
286
+ transition-duration: .20s;
287
+ -webkit-transition-property: height, visibility;
288
+ -o-transition-property: height, visibility;
289
+ transition-property: height, visibility
290
+ }
291
+
292
+ .mo2f_thumbnail {
293
+ width: 315px;
294
+ margin-bottom: 10px;
295
+ position: relative;
296
+ background-color: #fff;
297
+ border: 1px solid #ddd;
298
+ -webkit-transition: border .2s ease-in-out;
299
+ -o-transition: border .2s ease-in-out;
300
+ transition: border .2s ease-in-out
301
+ }
302
+
303
+ .mo2f_thumbnail > img, .mo2f_thumbnail a > img {
304
+ margin-right: auto;
305
+ margin-left: auto
306
+ }
307
+
308
+ a.mo2f_thumbnail:hover, a.mo2f_thumbnail:focus, a.mo2f_thumbnail.active {
309
+ border-color: #337ab7
310
+ }
311
+
312
+ .mo2f_thumbnail .caption {
313
+ padding: 9px;
314
+ color: #333
315
+ }
316
+
317
+ .mo2f_thumbnail label {
318
+ font-weight: bold;
319
+
320
+ }
321
+
322
+ .mo2f_close {
323
+ float: right;
324
+ font-size: 21px;
325
+ font-weight: 700;
326
+ line-height: 1;
327
+ color: #000;
328
+ text-shadow: 0 1px 0 #fff;
329
+ filter: alpha(opacity=20);
330
+ opacity: .2
331
+ }
332
+
333
+ .mo2f_close:hover, .mo2f_close:focus {
334
+ color: #000;
335
+ text-decoration: none;
336
+ cursor: pointer;
337
+ filter: alpha(opacity=50);
338
+ opacity: .5
339
+ }
340
+
341
+ button.mo2f_close {
342
+ -webkit-appearance: none;
343
+ padding: 0;
344
+ cursor: pointer;
345
+ background: 0 0;
346
+ border: 0
347
+ }
348
+
349
+ .mo2f_modal-open {
350
+ overflow: hidden !important;
351
+ position: fixed !important;
352
+ width: 100% !important;
353
+
354
+ }
355
+
356
+ .mo2f_modal {
357
+ position: fixed !important;
358
+ top: 0;
359
+ right: 0;
360
+ bottom: 0;
361
+ left: 0;
362
+ z-index: 100000 !important;
363
+
364
+ overflow: hidden !important;
365
+ -webkit-overflow-scrolling: touch;
366
+ outline: 0;
367
+
368
+ }
369
+
370
+ .mo2f_modal_inner {
371
+ display: none;
372
+ }
373
+
374
+ .mo2f_modal.fade .mo2f_modal-dialog {
375
+ -webkit-transition: -webkit-transform .3s ease-out;
376
+ -o-transition: -o-transform .3s ease-out;
377
+ transition: transform .3s ease-out;
378
+ -webkit-transform: translate(0, -25%);
379
+ -ms-transform: translate(0, -25%);
380
+ -o-transform: translate(0, -25%);
381
+ transform: translate(0, -25%)
382
+ }
383
+
384
+ .mo2f_modal.in .mo2f_modal-dialog {
385
+ -webkit-transform: translate(0, 80px) !important;
386
+ -ms-transform: translate(0, 80px) !important;
387
+ -o-transform: translate(0, 80px) !important;
388
+ transform: translate(0, 80px) !important;
389
+
390
+ }
391
+
392
+ .mo2f_modal-open .mo2f_modal {
393
+ overflow-x: hidden;
394
+ overflow-y: hidden;
395
+ }
396
+
397
+ .mo2f_modal-dialog {
398
+ position: relative;
399
+ width: auto;
400
+ margin: 10px;
401
+
402
+ }
403
+
404
+ .login mo_customer_validation-modal-content {
405
+ position: relative !important;
406
+ background-color: #fff !important;
407
+ -webkit-background-clip: padding-box !important;
408
+ background-clip: padding-box !important;
409
+ border: 1px solid #999 !important;
410
+ border: 1px solid rgba(0, 0, 0, .2) !important;
411
+ border-radius: 6px !important;
412
+ outline: 0 !important;
413
+
414
+ -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5) !important;
415
+ box-shadow: 0 3px 9px rgba(0, 0, 0, .5) !important;
416
+ }
417
+
418
+ .mo2f-modal-backdrop {
419
+ position: absolute;
420
+ top: 0;
421
+ right: 0;
422
+ left: 0;
423
+ background-color: #f1f1f1 !important;
424
+ filter: alpha(opacity=50) !important;
425
+ opacity: 0.8 !important;
426
+ height: 100% !important;
427
+ }
428
+
429
+ #smsAlertModal {
430
+ background-color: black !important;
431
+ opacity: 0.8 !important;
432
+ font-family: Roboto;
433
+ }
434
+
435
+ #twoFAtestAlertModal {
436
+ background-color: black !important;
437
+ opacity: 0.8 !important;
438
+ filter: alpha(opacity=50) !important;
439
+ }
440
+
441
+ .mo2f_modal-header {
442
+ min-height: 14px;
443
+ padding: 10px;
444
+ border-bottom: 1px solid #e5e5e5
445
+ }
446
+
447
+ .mo2f_modal-title {
448
+ margin: 0 !important;
449
+ line-height: 1.0 !important;
450
+ font-size: 1rem;
451
+ }
452
+
453
+ .mo2f_modal-body {
454
+ / / width: 96 % !important;
455
+ position: relative !important;
456
+ padding: 15px !important;
457
+ overflow-y: auto !important;
458
+ max-height: 550px !important;
459
+ }
460
+
461
+ .mo2f_modal-footer {
462
+ padding: 15px;
463
+ text-align: right;
464
+ border-top: 1px solid #e5e5e5
465
+ }
466
+
467
+ .mo2f_modal-footer .btn + .btn {
468
+ margin-bottom: 0;
469
+ margin-left: 5px
470
+ }
471
+
472
+ .mo2f_modal-footer .btn-group .btn + .btn {
473
+ margin-left: -1px
474
+ }
475
+
476
+ .mo2f_modal-footer .btn-block + .btn-block {
477
+ margin-left: 0
478
+ }
479
+
480
+ .mo2f_modal-scrollbar-measure {
481
+ position: absolute;
482
+ top: -9999px;
483
+ width: 50px;
484
+ height: 50px;
485
+ overflow: scroll
486
+ }
487
+
488
+ @media ( min-width: 768px) {
489
+ .mo2f_modal-dialog {
490
+ width: 373px;
491
+ margin: 0px auto
492
+ }
493
+
494
+ .login mo_customer_validation-modal-content {
495
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
496
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5)
497
+ }
498
+
499
+ .mo2f_modal-sm {
500
+ width: 300px
501
+ }
502
+
503
+ .mo2f_modal-md {
504
+ width: 550px
505
+ }
506
+ }
507
+
508
+ @media ( min-width: 992px) {
509
+ .mo2f_modal-lg {
510
+ width: 900px;
511
+ }
512
+
513
+ .mo2f_modal-md {
514
+ width: 550px
515
+ }
516
+ }
517
+
518
+ .center{
519
+
520
+ text-align: center !important;
521
+ }
522
+
523
+ #otpMessage {
524
+ border-radius: 1px;
525
+ padding: 1px 5px;
526
+ background: #f1f1f1;
527
+ }
528
+
529
+ .mo2f_carousel-indicators {
530
+ position: absolute;
531
+ bottom: -20px;
532
+ z-index: 15;
533
+ width: 60%;
534
+ list-style: none;
535
+ text-align: center;
536
+ }
537
+
538
+ .miniorange_kba_validate:hover, .miniorange_validate_otp:hover, .miniorange_login_forgotphone:hover,
539
+ .miniorange_login_offline:hover, .miniorange_login_forgotphone:hover, .miniorange_otp_token_submit:hover {
540
+ background-color: #0073AA !important
541
+ }
542
+
543
+ .miniorange_kba_validate, .miniorange_validate_otp, .miniorange_login_forgotphone,
544
+ .miniorange_login_offline, .miniorange_login_forgotphone, .miniorange_otp_token_submit {
545
+ background: #00A0D2 !important;
546
+ border-color: #0073AA !important;
547
+ box-shadow: 0 1px 0 rgba(120, 200, 230, .5) inset, 0 1px 0 rgba(0, 0, 0, .15) !important;
548
+ color: #FFF !important;
549
+ text-decoration: none !important;
550
+ cursor: pointer !important;
551
+ border-width: 1px !important;
552
+ border-style: solid !important;
553
+ border-radius: 3px !important;
554
+ white-space: nowrap !important;
555
+ box-sizing: border-box !important;
556
+ line-height: 28px !important;
557
+ padding: 0 12px !important;
558
+ font-size: 13px !important
559
+ }
560
+
561
+ .mo_customer_validation-modal.fade .mo_customer_validation-modal-dialog {
562
+ -webkit-transition: -webkit-transform .3s ease-out;
563
+ -o-transition: -o-transform .3s ease-out;
564
+ transition: transform .3s ease-out;
565
+ -webkit-transform: translate(0, -25%);
566
+ -ms-transform: translate(0, -25%);
567
+ -o-transform: translate(0, -25%);
568
+ transform: translate(0, -25%)
569
+ }
570
+
571
+ .mo_customer_validation-modal.in .mo_customer_validation-modal-dialog {
572
+ -webkit-transform: translate(0, 80px) !important;
573
+ -ms-transform: translate(0, 80px) !important;
574
+ -o-transform: translate(0, 80px) !important;
575
+ transform: translate(0, 80px) !important
576
+ }
577
+
578
+ .mo_customer_validation-modal-open .mo_customer_validation-modal {
579
+ overflow-x: hidden;
580
+ overflow-y: hidden
581
+ }
582
+
583
+ .mo_customer_validation-modal-dialog {
584
+ position: relative;
585
+ width: auto;
586
+ margin: 10px
587
+ }
588
+
589
+ .mo_customer_validation-modal-content {
590
+ position: relative;
591
+ -webkit-background-clip: padding-box;
592
+ border: 1px solid #999;
593
+ border: 1px solid rgba(0, 0, 0, .2);
594
+ outline: 0;
595
+ margin-top: 8%;
596
+ margin-left: 0;
597
+ padding: 15px 20px 0;
598
+ font-family: "Open Sans", sans-serif;
599
+ color: #777;
600
+ font-size: 14px;
601
+ line-height: 1.4em;
602
+ background: #FFF;
603
+ box-shadow: 0 1px 3px rgba(0, 0, 0, .13)
604
+ }
605
+
606
+ .mo_customer_validation-modal-backdrop {
607
+ position: absolute;
608
+ top: 0;
609
+ right: 0;
610
+ left: 0;
611
+ background-color: #000 !important;
612
+ filter: alpha(opacity=50) !important;
613
+ opacity: .9 !important;
614
+ height: 100% !important
615
+ }
616
+
617
+ .mo_customer_validation-modal-header {
618
+ min-height: 14px;
619
+ padding: 10px 10px 20px;
620
+ border-bottom: 1px solid #e5e5e5
621
+ }
622
+
623
+ .mo_customer_validation-modal-title {
624
+ margin: 0 !important;
625
+ line-height: 1 !important
626
+ }
627
+
628
+ .mo_customer_validation-modal-body {
629
+ position: relative;
630
+ padding: 5%;
631
+ overflow: hidden !important;
632
+ max-height: 550px !important
633
+ }
634
+
635
+ .mo_customer_validation-modal-footer {
636
+ padding: 15px;
637
+ text-align: right;
638
+ border-top: 1px solid #e5e5e5
639
+ }
640
+
641
+ .mo_customer_validation-modal-footer .btn + .btn {
642
+ margin-bottom: 0;
643
+ margin-left: 5px
644
+ }
645
+
646
+ .mo_customer_validation-modal-footer .btn-group .btn + .btn {
647
+ margin-left: -1px
648
+ }
649
+
650
+ .mo_customer_validation-modal-footer .btn-block + .btn-block {
651
+ margin-left: 0
652
+ }
653
+
654
+ .mo_customer_validation-modal-scrollbar-measure {
655
+ position: absolute;
656
+ top: -9999px;
657
+ width: 50px;
658
+ height: 50px;
659
+ overflow: scroll
660
+ }
661
+
662
+ @media (min-width: 768px) {
663
+ .mo_customer_validation-modal-dialog {
664
+ width: auto;
665
+ margin: 0 auto
666
+ }
667
+
668
+ .mo_customer_validation-modal-content {
669
+ -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
670
+ box-shadow: 0 5px 15px rgba(0, 0, 0, .5)
671
+ }
672
+
673
+ .mo_customer_validation-modal-sm {
674
+ width: 300px
675
+ }
676
+
677
+ .mo_customer_validation-modal-md {
678
+ width: 532px
679
+ }
680
+
681
+ .mo_customer_validation-modal-lg {
682
+ width: 50%
683
+ }
684
+ }
685
+
686
+ @media (min-width: 992px) {
687
+ .mo_customer_validation-modal-dialog {
688
+ width: auto;
689
+ margin: 0 auto
690
+ }
691
+
692
+ .mo_customer_validation-modal-lg {
693
+ width: 490px
694
+ }
695
+
696
+ .mo_customer_validation-modal-md {
697
+ width: 532px
698
+ }
699
+ }
700
+
701
+ .mo_customer_validation-textbox {
702
+ background: #FBFBFB;
703
+ font-family: "Open Sans", sans-serif;
704
+ font-size: 24px;
705
+ width: 100%;
706
+ border: 1px solid #DDD;
707
+ padding: 3px;
708
+ margin: 2px 6px 16px 0
709
+ }
710
+
711
+ .mo_customer_validation-textbox:focus {
712
+ border-color: #5B9DD9;
713
+ box-shadow: 0 0 2px rgba(30, 140, 190, .8)
714
+ }
715
+
716
+ .button-primary,
717
+ .button-secondary {
718
+ background: #00A0D2;
719
+ border-color: #0073AA;
720
+ box-shadow: 0 1px 0 rgba(120, 200, 230, .5) inset, 0 1px 0 rgba(0, 0, 0, .15);
721
+ color: #FFF;
722
+ text-decoration: none;
723
+ cursor: pointer;
724
+ border-width: 1px;
725
+ border-style: solid;
726
+ border-radius: 3px;
727
+ white-space: nowrap;
728
+ box-sizing: border-box;
729
+ line-height: 28px;
730
+ padding: 0 12px;
731
+ font-size: 13px
732
+ }
733
+
734
+ .button:hover {
735
+ background-color: #0073AA
736
+ }
737
+
738
+ .close {
739
+ float: right;
740
+ transition: color .1s ease-in-out, background .1s ease-in-out;
741
+ text-decoration: none;
742
+ color: #999;
743
+ font-size: 13px
744
+ }
745
+
746
+ .mo_validate_close:focus,
747
+ .mo_validate_close:hover {
748
+ color: #0085ba
749
+ }
750
+
751
+ .mo_registration_pricing_text {
752
+ font-size: 13px;
753
+ color: darkblue;
754
+ }
755
+
756
+ .mo_otp_token {
757
+ font-size: 15px;
758
+ color: #212F3C;
759
+ border: none;
760
+ display: block;
761
+ border-bottom-style: solid;
762
+ border-width: 2px;
763
+ border-color: #D0D3D4;
764
+ border-radius: 0px;
765
+ outline: none;
766
+ width: 140px;
767
+ text-align: center;
768
+ }
769
+
770
+ .container {
771
+ max-width: 960px
772
+ }
773
+
774
+ }
775
+ @media (min-width: 1200px) {
776
+ .container {
777
+ max-width: 1140px
778
+ }
779
+ }
780
+
781
+ .container-fluid {
782
+ width: 100%;
783
+ padding-right: 15px;
784
+ padding-left: 15px;
785
+ margin-right: auto;
786
+ margin-left: auto
787
+ }
788
+
789
+ .row {
790
+ display: -webkit-box;
791
+ display: -ms-flexbox;
792
+ display: flex;
793
+ -ms-flex-wrap: wrap;
794
+ flex-wrap: wrap;
795
+ margin-right: -15px;
796
+ margin-left: -15px
797
+ }
798
+
799
+ .no-gutters {
800
+ margin-right: 0;
801
+ margin-left: 0
802
+ }
803
+
804
+ .no-gutters > .col, .no-gutters > [class*=col-] {
805
+ padding-right: 0;
806
+ padding-left: 0
807
+ }
808
+
809
+ .col, .col-1, .col-10, .col-11, .col-12, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-auto, .col-lg, .col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-auto, .col-md, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-auto, .col-sm, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-auto {
810
+ position: relative;
811
+ width: 100%;
812
+ min-height: 1px;
813
+ padding-right: 15px;
814
+ padding-left: 15px
815
+ }
816
+
817
+ .col {
818
+ -ms-flex-preferred-size: 0;
819
+ flex-basis: 0;
820
+ -webkit-box-flex: 1;
821
+ -ms-flex-positive: 1;
822
+ flex-grow: 1;
823
+ max-width: 100%
824
+ }
825
+
826
+ .col-auto {
827
+ -webkit-box-flex: 0;
828
+ -ms-flex: 0 0 auto;
829
+ flex: 0 0 auto;
830
+ width: auto;
831
+ max-width: none
832
+ }
833
+
834
+ .col-1 {
835
+ -webkit-box-flex: 0;
836
+ -ms-flex: 0 0 8.333333%;
837
+ flex: 0 0 8.333333%;
838
+ max-width: 8.333333%
839
+ }
840
+
841
+ .col-2 {
842
+ -webkit-box-flex: 0;
843
+ -ms-flex: 0 0 16.666667%;
844
+ flex: 0 0 16.666667%;
845
+ max-width: 16.666667%
846
+ }
847
+
848
+ .col-3 {
849
+ -webkit-box-flex: 0;
850
+ -ms-flex: 0 0 25%;
851
+ flex: 0 0 25%;
852
+ max-width: 25%
853
+ }
854
+
855
+ .col-4 {
856
+ -webkit-box-flex: 0;
857
+ -ms-flex: 0 0 33.333333%;
858
+ flex: 0 0 33.333333%;
859
+ max-width: 33.333333%
860
+ }
861
+
862
+ .col-5 {
863
+ -webkit-box-flex: 0;
864
+ -ms-flex: 0 0 41.666667%;
865
+ flex: 0 0 41.666667%;
866
+ max-width: 41.666667%
867
+ }
868
+
869
+ .col-6 {
870
+ -webkit-box-flex: 0;
871
+ -ms-flex: 0 0 50%;
872
+ flex: 0 0 50%;
873
+ max-width: 50%
874
+ }
875
+
876
+ .col-7 {
877
+ -webkit-box-flex: 0;
878
+ -ms-flex: 0 0 58.333333%;
879
+ flex: 0 0 58.333333%;
880
+ max-width: 58.333333%
881
+ }
882
+
883
+ .col-8 {
884
+ -webkit-box-flex: 0;
885
+ -ms-flex: 0 0 66.666667%;
886
+ flex: 0 0 66.666667%;
887
+ max-width: 66.666667%
888
+ }
889
+
890
+ .col-9 {
891
+ -webkit-box-flex: 0;
892
+ -ms-flex: 0 0 75%;
893
+ flex: 0 0 75%;
894
+ max-width: 75%
895
+ }
896
+
897
+ .col-10 {
898
+ -webkit-box-flex: 0;
899
+ -ms-flex: 0 0 83.333333%;
900
+ flex: 0 0 83.333333%;
901
+ max-width: 83.333333%
902
+ }
903
+
904
+ .col-11 {
905
+ -webkit-box-flex: 0;
906
+ -ms-flex: 0 0 91.666667%;
907
+ flex: 0 0 91.666667%;
908
+ max-width: 91.666667%
909
+ }
910
+
911
+ .col-12 {
912
+ -webkit-box-flex: 0;
913
+ -ms-flex: 0 0 100%;
914
+ flex: 0 0 100%;
915
+ max-width: 100%
916
+ }
917
+
918
+ .order-first {
919
+ -webkit-box-ordinal-group: 0;
920
+ -ms-flex-order: -1;
921
+ order: -1
922
+ }
923
+
924
+ .order-last {
925
+ -webkit-box-ordinal-group: 14;
926
+ -ms-flex-order: 13;
927
+ order: 13
928
+ }
929
+
930
+ .order-0 {
931
+ -webkit-box-ordinal-group: 1;
932
+ -ms-flex-order: 0;
933
+ order: 0
934
+ }
935
+
936
+ .order-1 {
937
+ -webkit-box-ordinal-group: 2;
938
+ -ms-flex-order: 1;
939
+ order: 1
940
+ }
941
+
942
+ .order-2 {
943
+ -webkit-box-ordinal-group: 3;
944
+ -ms-flex-order: 2;
945
+ order: 2
946
+ }
947
+
948
+ .order-3 {
949
+ -webkit-box-ordinal-group: 4;
950
+ -ms-flex-order: 3;
951
+ order: 3
952
+ }
953
+
954
+ .order-4 {
955
+ -webkit-box-ordinal-group: 5;
956
+ -ms-flex-order: 4;
957
+ order: 4
958
+ }
959
+
960
+ .order-5 {
961
+ -webkit-box-ordinal-group: 6;
962
+ -ms-flex-order: 5;
963
+ order: 5
964
+ }
965
+
966
+ .order-6 {
967
+ -webkit-box-ordinal-group: 7;
968
+ -ms-flex-order: 6;
969
+ order: 6
970
+ }
971
+
972
+ .order-7 {
973
+ -webkit-box-ordinal-group: 8;
974
+ -ms-flex-order: 7;
975
+ order: 7
976
+ }
977
+
978
+ .order-8 {
979
+ -webkit-box-ordinal-group: 9;
980
+ -ms-flex-order: 8;
981
+ order: 8
982
+ }
983
+
984
+ .order-9 {
985
+ -webkit-box-ordinal-group: 10;
986
+ -ms-flex-order: 9;
987
+ order: 9
988
+ }
989
+
990
+ .order-10 {
991
+ -webkit-box-ordinal-group: 11;
992
+ -ms-flex-order: 10;
993
+ order: 10
994
+ }
995
+
996
+ .order-11 {
997
+ -webkit-box-ordinal-group: 12;
998
+ -ms-flex-order: 11;
999
+ order: 11
1000
+ }
1001
+
1002
+ .order-12 {
1003
+ -webkit-box-ordinal-group: 13;
1004
+ -ms-flex-order: 12;
1005
+ order: 12
1006
+ }
1007
+
1008
+ .offset-1 {
1009
+ margin-left: 8.333333%
1010
+ }
1011
+
1012
+ .offset-2 {
1013
+ margin-left: 16.666667%
1014
+ }
1015
+
1016
+ .offset-3 {
1017
+ margin-left: 25%
1018
+ }
1019
+
1020
+ .offset-4 {
1021
+ margin-left: 33.333333%
1022
+ }
1023
+
1024
+ .offset-5 {
1025
+ margin-left: 41.666667%
1026
+ }
1027
+
1028
+ .offset-6 {
1029
+ margin-left: 50%
1030
+ }
1031
+
1032
+ .offset-7 {
1033
+ margin-left: 58.333333%
1034
+ }
1035
+
1036
+ .offset-8 {
1037
+ margin-left: 66.666667%
1038
+ }
1039
+
1040
+ .offset-9 {
1041
+ margin-left: 75%
1042
+ }
1043
+
1044
+ .offset-10 {
1045
+ margin-left: 83.333333%
1046
+ }
1047
+
1048
+ .offset-11 {
1049
+ margin-left: 91.666667%
1050
+ }
1051
+
1052
+ @media (min-width: 576px) {
1053
+ .col-sm {
1054
+ -ms-flex-preferred-size: 0;
1055
+ flex-basis: 0;
1056
+ -webkit-box-flex: 1;
1057
+ -ms-flex-positive: 1;
1058
+ flex-grow: 1;
1059
+ max-width: 100%
1060
+ }
1061
+
1062
+ .col-sm-auto {
1063
+ -webkit-box-flex: 0;
1064
+ -ms-flex: 0 0 auto;
1065
+ flex: 0 0 auto;
1066
+ width: auto;
1067
+ max-width: none
1068
+ }
1069
+
1070
+ .col-sm-1 {
1071
+ -webkit-box-flex: 0;
1072
+ -ms-flex: 0 0 8.333333%;
1073
+ flex: 0 0 8.333333%;
1074
+ max-width: 8.333333%
1075
+ }
1076
+
1077
+ .col-sm-2 {
1078
+ -webkit-box-flex: 0;
1079
+ -ms-flex: 0 0 16.666667%;
1080
+ flex: 0 0 16.666667%;
1081
+ max-width: 16.666667%
1082
+ }
1083
+
1084
+ .col-sm-3 {
1085
+ -webkit-box-flex: 0;
1086
+ -ms-flex: 0 0 25%;
1087
+ flex: 0 0 25%;
1088
+ max-width: 25%
1089
+ }
1090
+
1091
+ .col-sm-4 {
1092
+ -webkit-box-flex: 0;
1093
+ -ms-flex: 0 0 33.333333%;
1094
+ flex: 0 0 33.333333%;
1095
+ max-width: 33.333333%
1096
+ }
1097
+
1098
+ .col-sm-5 {
1099
+ -webkit-box-flex: 0;
1100
+ -ms-flex: 0 0 41.666667%;
1101
+ flex: 0 0 41.666667%;
1102
+ max-width: 41.666667%
1103
+ }
1104
+
1105
+ .col-sm-6 {
1106
+ -webkit-box-flex: 0;
1107
+ -ms-flex: 0 0 50%;
1108
+ flex: 0 0 50%;
1109
+ max-width: 50%
1110
+ }
1111
+
1112
+ .col-sm-7 {
1113
+ -webkit-box-flex: 0;
1114
+ -ms-flex: 0 0 58.333333%;
1115
+ flex: 0 0 58.333333%;
1116
+ max-width: 58.333333%
1117
+ }
1118
+
1119
+ .col-sm-8 {
1120
+ -webkit-box-flex: 0;
1121
+ -ms-flex: 0 0 66.666667%;
1122
+ flex: 0 0 66.666667%;
1123
+ max-width: 66.666667%
1124
+ }
1125
+
1126
+ .col-sm-9 {
1127
+ -webkit-box-flex: 0;
1128
+ -ms-flex: 0 0 75%;
1129
+ flex: 0 0 75%;
1130
+ max-width: 75%
1131
+ }
1132
+
1133
+ .col-sm-10 {
1134
+ -webkit-box-flex: 0;
1135
+ -ms-flex: 0 0 83.333333%;
1136
+ flex: 0 0 83.333333%;
1137
+ max-width: 83.333333%
1138
+ }
1139
+
1140
+ .col-sm-11 {
1141
+ -webkit-box-flex: 0;
1142
+ -ms-flex: 0 0 91.666667%;
1143
+ flex: 0 0 91.666667%;
1144
+ max-width: 91.666667%
1145
+ }
1146
+
1147
+ .col-sm-12 {
1148
+ -webkit-box-flex: 0;
1149
+ -ms-flex: 0 0 100%;
1150
+ flex: 0 0 100%;
1151
+ max-width: 100%
1152
+ }
1153
+
1154
+ .order-sm-first {
1155
+ -webkit-box-ordinal-group: 0;
1156
+ -ms-flex-order: -1;
1157
+ order: -1
1158
+ }
1159
+
1160
+ .order-sm-last {
1161
+ -webkit-box-ordinal-group: 14;
1162
+ -ms-flex-order: 13;
1163
+ order: 13
1164
+ }
1165
+
1166
+ .order-sm-0 {
1167
+ -webkit-box-ordinal-group: 1;
1168
+ -ms-flex-order: 0;
1169
+ order: 0
1170
+ }
1171
+
1172
+ .order-sm-1 {
1173
+ -webkit-box-ordinal-group: 2;
1174
+ -ms-flex-order: 1;
1175
+ order: 1
1176
+ }
1177
+
1178
+ .order-sm-2 {
1179
+ -webkit-box-ordinal-group: 3;
1180
+ -ms-flex-order: 2;
1181
+ order: 2
1182
+ }
1183
+
1184
+ .order-sm-3 {
1185
+ -webkit-box-ordinal-group: 4;
1186
+ -ms-flex-order: 3;
1187
+ order: 3
1188
+ }
1189
+
1190
+ .order-sm-4 {
1191
+ -webkit-box-ordinal-group: 5;
1192
+ -ms-flex-order: 4;
1193
+ order: 4
1194
+ }
1195
+
1196
+ .order-sm-5 {
1197
+ -webkit-box-ordinal-group: 6;
1198
+ -ms-flex-order: 5;
1199
+ order: 5
1200
+ }
1201
+
1202
+ .order-sm-6 {
1203
+ -webkit-box-ordinal-group: 7;
1204
+ -ms-flex-order: 6;
1205
+ order: 6
1206
+ }
1207
+
1208
+ .order-sm-7 {
1209
+ -webkit-box-ordinal-group: 8;
1210
+ -ms-flex-order: 7;
1211
+ order: 7
1212
+ }
1213
+
1214
+ .order-sm-8 {
1215
+ -webkit-box-ordinal-group: 9;
1216
+ -ms-flex-order: 8;
1217
+ order: 8
1218
+ }
1219
+
1220
+ .order-sm-9 {
1221
+ -webkit-box-ordinal-group: 10;
1222
+ -ms-flex-order: 9;
1223
+ order: 9
1224
+ }
1225
+
1226
+ .order-sm-10 {
1227
+ -webkit-box-ordinal-group: 11;
1228
+ -ms-flex-order: 10;
1229
+ order: 10
1230
+ }
1231
+
1232
+ .order-sm-11 {
1233
+ -webkit-box-ordinal-group: 12;
1234
+ -ms-flex-order: 11;
1235
+ order: 11
1236
+ }
1237
+
1238
+ .order-sm-12 {
1239
+ -webkit-box-ordinal-group: 13;
1240
+ -ms-flex-order: 12;
1241
+ order: 12
1242
+ }
1243
+
1244
+ .offset-sm-0 {
1245
+ margin-left: 0
1246
+ }
1247
+
1248
+ .offset-sm-1 {
1249
+ margin-left: 8.333333%
1250
+ }
1251
+
1252
+ .offset-sm-2 {
1253
+ margin-left: 16.666667%
1254
+ }
1255
+
1256
+ .offset-sm-3 {
1257
+ margin-left: 25%
1258
+ }
1259
+
1260
+ .offset-sm-4 {
1261
+ margin-left: 33.333333%
1262
+ }
1263
+
1264
+ .offset-sm-5 {
1265
+ margin-left: 41.666667%
1266
+ }
1267
+
1268
+ .offset-sm-6 {
1269
+ margin-left: 50%
1270
+ }
1271
+
1272
+ .offset-sm-7 {
1273
+ margin-left: 58.333333%
1274
+ }
1275
+
1276
+ .offset-sm-8 {
1277
+ margin-left: 66.666667%
1278
+ }
1279
+
1280
+ .offset-sm-9 {
1281
+ margin-left: 75%
1282
+ }
1283
+
1284
+ .offset-sm-10 {
1285
+ margin-left: 83.333333%
1286
+ }
1287
+
1288
+ .offset-sm-11 {
1289
+ margin-left: 91.666667%
1290
+ }
1291
+ }
1292
+
1293
+ @media (min-width: 768px) {
1294
+ .col-md {
1295
+ -ms-flex-preferred-size: 0;
1296
+ flex-basis: 0;
1297
+ -webkit-box-flex: 1;
1298
+ -ms-flex-positive: 1;
1299
+ flex-grow: 1;
1300
+ max-width: 100%
1301
+ }
1302
+
1303
+ .col-md-auto {
1304
+ -webkit-box-flex: 0;
1305
+ -ms-flex: 0 0 auto;
1306
+ flex: 0 0 auto;
1307
+ width: auto;
1308
+ max-width: none
1309
+ }
1310
+
1311
+ .col-md-1 {
1312
+ -webkit-box-flex: 0;
1313
+ -ms-flex: 0 0 8.333333%;
1314
+ flex: 0 0 8.333333%;
1315
+ max-width: 8.333333%
1316
+ }
1317
+
1318
+ .col-md-2 {
1319
+ -webkit-box-flex: 0;
1320
+ -ms-flex: 0 0 16.666667%;
1321
+ flex: 0 0 16.666667%;
1322
+ max-width: 16.666667%
1323
+ }
1324
+
1325
+ .col-md-3 {
1326
+ -webkit-box-flex: 0;
1327
+ -ms-flex: 0 0 25%;
1328
+ flex: 0 0 25%;
1329
+ max-width: 25%
1330
+ }
1331
+
1332
+ .col-md-4 {
1333
+ -webkit-box-flex: 0;
1334
+ -ms-flex: 0 0 33.333333%;
1335
+ flex: 0 0 33.333333%;
1336
+ max-width: 33.333333%
1337
+ }
1338
+
1339
+ .col-md-5 {
1340
+ -webkit-box-flex: 0;
1341
+ -ms-flex: 0 0 41.666667%;
1342
+ flex: 0 0 41.666667%;
1343
+ max-width: 41.666667%
1344
+ }
1345
+
1346
+ .col-md-6 {
1347
+ -webkit-box-flex: 0;
1348
+ -ms-flex: 0 0 50%;
1349
+ flex: 0 0 50%;
1350
+ max-width: 50%
1351
+ }
1352
+
1353
+ .col-md-7 {
1354
+ -webkit-box-flex: 0;
1355
+ -ms-flex: 0 0 58.333333%;
1356
+ flex: 0 0 58.333333%;
1357
+ max-width: 58.333333%
1358
+ }
1359
+
1360
+ .col-md-8 {
1361
+ -webkit-box-flex: 0;
1362
+ -ms-flex: 0 0 66.666667%;
1363
+ flex: 0 0 66.666667%;
1364
+ max-width: 66.666667%
1365
+ }
1366
+
1367
+ .col-md-9 {
1368
+ -webkit-box-flex: 0;
1369
+ -ms-flex: 0 0 75%;
1370
+ flex: 0 0 75%;
1371
+ max-width: 75%
1372
+ }
1373
+
1374
+ .col-md-10 {
1375
+ -webkit-box-flex: 0;
1376
+ -ms-flex: 0 0 83.333333%;
1377
+ flex: 0 0 83.333333%;
1378
+ max-width: 83.333333%
1379
+ }
1380
+
1381
+ .col-md-11 {
1382
+ -webkit-box-flex: 0;
1383
+ -ms-flex: 0 0 91.666667%;
1384
+ flex: 0 0 91.666667%;
1385
+ max-width: 91.666667%
1386
+ }
1387
+
1388
+ .col-md-12 {
1389
+ -webkit-box-flex: 0;
1390
+ -ms-flex: 0 0 100%;
1391
+ flex: 0 0 100%;
1392
+ max-width: 100%
1393
+ }
1394
+
1395
+ .order-md-first {
1396
+ -webkit-box-ordinal-group: 0;
1397
+ -ms-flex-order: -1;
1398
+ order: -1
1399
+ }
1400
+
1401
+ .order-md-last {
1402
+ -webkit-box-ordinal-group: 14;
1403
+ -ms-flex-order: 13;
1404
+ order: 13
1405
+ }
1406
+
1407
+ .order-md-0 {
1408
+ -webkit-box-ordinal-group: 1;
1409
+ -ms-flex-order: 0;
1410
+ order: 0
1411
+ }
1412
+
1413
+ .order-md-1 {
1414
+ -webkit-box-ordinal-group: 2;
1415
+ -ms-flex-order: 1;
1416
+ order: 1
1417
+ }
1418
+
1419
+ .order-md-2 {
1420
+ -webkit-box-ordinal-group: 3;
1421
+ -ms-flex-order: 2;
1422
+ order: 2
1423
+ }
1424
+
1425
+ .order-md-3 {
1426
+ -webkit-box-ordinal-group: 4;
1427
+ -ms-flex-order: 3;
1428
+ order: 3
1429
+ }
1430
+
1431
+ .order-md-4 {
1432
+ -webkit-box-ordinal-group: 5;
1433
+ -ms-flex-order: 4;
1434
+ order: 4
1435
+ }
1436
+
1437
+ .order-md-5 {
1438
+ -webkit-box-ordinal-group: 6;
1439
+ -ms-flex-order: 5;
1440
+ order: 5
1441
+ }
1442
+
1443
+ .order-md-6 {
1444
+ -webkit-box-ordinal-group: 7;
1445
+ -ms-flex-order: 6;
1446
+ order: 6
1447
+ }
1448
+
1449
+ .order-md-7 {
1450
+ -webkit-box-ordinal-group: 8;
1451
+ -ms-flex-order: 7;
1452
+ order: 7
1453
+ }
1454
+
1455
+ .order-md-8 {
1456
+ -webkit-box-ordinal-group: 9;
1457
+ -ms-flex-order: 8;
1458
+ order: 8
1459
+ }
1460
+
1461
+ .order-md-9 {
1462
+ -webkit-box-ordinal-group: 10;
1463
+ -ms-flex-order: 9;
1464
+ order: 9
1465
+ }
1466
+
1467
+ .order-md-10 {
1468
+ -webkit-box-ordinal-group: 11;
1469
+ -ms-flex-order: 10;
1470
+ order: 10
1471
+ }
1472
+
1473
+ .order-md-11 {
1474
+ -webkit-box-ordinal-group: 12;
1475
+ -ms-flex-order: 11;
1476
+ order: 11
1477
+ }
1478
+
1479
+ .order-md-12 {
1480
+ -webkit-box-ordinal-group: 13;
1481
+ -ms-flex-order: 12;
1482
+ order: 12
1483
+ }
1484
+
1485
+ .offset-md-0 {
1486
+ margin-left: 0
1487
+ }
1488
+
1489
+ .offset-md-1 {
1490
+ margin-left: 8.333333%
1491
+ }
1492
+
1493
+ .offset-md-2 {
1494
+ margin-left: 16.666667%
1495
+ }
1496
+
1497
+ .offset-md-3 {
1498
+ margin-left: 25%
1499
+ }
1500
+
1501
+ .offset-md-4 {
1502
+ margin-left: 33.333333%
1503
+ }
1504
+
1505
+ .offset-md-5 {
1506
+ margin-left: 41.666667%
1507
+ }
1508
+
1509
+ .offset-md-6 {
1510
+ margin-left: 50%
1511
+ }
1512
+
1513
+ .offset-md-7 {
1514
+ margin-left: 58.333333%
1515
+ }
1516
+
1517
+ .offset-md-8 {
1518
+ margin-left: 66.666667%
1519
+ }
1520
+
1521
+ .offset-md-9 {
1522
+ margin-left: 75%
1523
+ }
1524
+
1525
+ .offset-md-10 {
1526
+ margin-left: 83.333333%
1527
+ }
1528
+
1529
+ .offset-md-11 {
1530
+ margin-left: 91.666667%
1531
+ }
1532
+ }
1533
+
1534
+ @media (min-width: 992px) {
1535
+ .col-lg {
1536
+ -ms-flex-preferred-size: 0;
1537
+ flex-basis: 0;
1538
+ -webkit-box-flex: 1;
1539
+ -ms-flex-positive: 1;
1540
+ flex-grow: 1;
1541
+ max-width: 100%
1542
+ }
1543
+
1544
+ .col-lg-auto {
1545
+ -webkit-box-flex: 0;
1546
+ -ms-flex: 0 0 auto;
1547
+ flex: 0 0 auto;
1548
+ width: auto;
1549
+ max-width: none
1550
+ }
1551
+
1552
+ .col-lg-1 {
1553
+ -webkit-box-flex: 0;
1554
+ -ms-flex: 0 0 8.333333%;
1555
+ flex: 0 0 8.333333%;
1556
+ max-width: 8.333333%
1557
+ }
1558
+
1559
+ .col-lg-2 {
1560
+ -webkit-box-flex: 0;
1561
+ -ms-flex: 0 0 16.666667%;
1562
+ flex: 0 0 16.666667%;
1563
+ max-width: 16.666667%
1564
+ }
1565
+
1566
+ .col-lg-3 {
1567
+ -webkit-box-flex: 0;
1568
+ -ms-flex: 0 0 25%;
1569
+ flex: 0 0 25%;
1570
+ max-width: 25%
1571
+ }
1572
+
1573
+ .col-lg-4 {
1574
+ -webkit-box-flex: 0;
1575
+ -ms-flex: 0 0 33.333333%;
1576
+ flex: 0 0 33.333333%;
1577
+ max-width: 33.333333%
1578
+ }
1579
+
1580
+ .col-lg-5 {
1581
+ -webkit-box-flex: 0;
1582
+ -ms-flex: 0 0 41.666667%;
1583
+ flex: 0 0 41.666667%;
1584
+ max-width: 41.666667%
1585
+ }
1586
+
1587
+ .col-lg-6 {
1588
+ -webkit-box-flex: 0;
1589
+ -ms-flex: 0 0 50%;
1590
+ flex: 0 0 50%;
1591
+ max-width: 50%
1592
+ }
1593
+
1594
+ .col-lg-7 {
1595
+ -webkit-box-flex: 0;
1596
+ -ms-flex: 0 0 58.333333%;
1597
+ flex: 0 0 58.333333%;
1598
+ max-width: 58.333333%
1599
+ }
1600
+
1601
+ .col-lg-8 {
1602
+ -webkit-box-flex: 0;
1603
+ -ms-flex: 0 0 66.666667%;
1604
+ flex: 0 0 66.666667%;
1605
+ max-width: 66.666667%
1606
+ }
1607
+
1608
+ .col-lg-9 {
1609
+ -webkit-box-flex: 0;
1610
+ -ms-flex: 0 0 75%;
1611
+ flex: 0 0 75%;
1612
+ max-width: 75%
1613
+ }
1614
+
1615
+ .col-lg-10 {
1616
+ -webkit-box-flex: 0;
1617
+ -ms-flex: 0 0 83.333333%;
1618
+ flex: 0 0 83.333333%;
1619
+ max-width: 83.333333%
1620
+ }
1621
+
1622
+ .col-lg-11 {
1623
+ -webkit-box-flex: 0;
1624
+ -ms-flex: 0 0 91.666667%;
1625
+ flex: 0 0 91.666667%;
1626
+ max-width: 91.666667%
1627
+ }
1628
+
1629
+ .col-lg-12 {
1630
+ -webkit-box-flex: 0;
1631
+ -ms-flex: 0 0 100%;
1632
+ flex: 0 0 100%;
1633
+ max-width: 100%
1634
+ }
1635
+
1636
+ .order-lg-first {
1637
+ -webkit-box-ordinal-group: 0;
1638
+ -ms-flex-order: -1;
1639
+ order: -1
1640
+ }
1641
+
1642
+ .order-lg-last {
1643
+ -webkit-box-ordinal-group: 14;
1644
+ -ms-flex-order: 13;
1645
+ order: 13
1646
+ }
1647
+
1648
+ .order-lg-0 {
1649
+ -webkit-box-ordinal-group: 1;
1650
+ -ms-flex-order: 0;
1651
+ order: 0
1652
+ }
1653
+
1654
+ .order-lg-1 {
1655
+ -webkit-box-ordinal-group: 2;
1656
+ -ms-flex-order: 1;
1657
+ order: 1
1658
+ }
1659
+
1660
+ .order-lg-2 {
1661
+ -webkit-box-ordinal-group: 3;
1662
+ -ms-flex-order: 2;
1663
+ order: 2
1664
+ }
1665
+
1666
+ .order-lg-3 {
1667
+ -webkit-box-ordinal-group: 4;
1668
+ -ms-flex-order: 3;
1669
+ order: 3
1670
+ }
1671
+
1672
+ .order-lg-4 {
1673
+ -webkit-box-ordinal-group: 5;
1674
+ -ms-flex-order: 4;
1675
+ order: 4
1676
+ }
1677
+
1678
+ .order-lg-5 {
1679
+ -webkit-box-ordinal-group: 6;
1680
+ -ms-flex-order: 5;
1681
+ order: 5
1682
+ }
1683
+
1684
+ .order-lg-6 {
1685
+ -webkit-box-ordinal-group: 7;
1686
+ -ms-flex-order: 6;
1687
+ order: 6
1688
+ }
1689
+
1690
+ .order-lg-7 {
1691
+ -webkit-box-ordinal-group: 8;
1692
+ -ms-flex-order: 7;
1693
+ order: 7
1694
+ }
1695
+
1696
+ .order-lg-8 {
1697
+ -webkit-box-ordinal-group: 9;
1698
+ -ms-flex-order: 8;
1699
+ order: 8
1700
+ }
1701
+
1702
+ .order-lg-9 {
1703
+ -webkit-box-ordinal-group: 10;
1704
+ -ms-flex-order: 9;
1705
+ order: 9
1706
+ }
1707
+
1708
+ .order-lg-10 {
1709
+ -webkit-box-ordinal-group: 11;
1710
+ -ms-flex-order: 10;
1711
+ order: 10
1712
+ }
1713
+
1714
+ .order-lg-11 {
1715
+ -webkit-box-ordinal-group: 12;
1716
+ -ms-flex-order: 11;
1717
+ order: 11
1718
+ }
1719
+
1720
+ .order-lg-12 {
1721
+ -webkit-box-ordinal-group: 13;
1722
+ -ms-flex-order: 12;
1723
+ order: 12
1724
+ }
1725
+
1726
+ .offset-lg-0 {
1727
+ margin-left: 0
1728
+ }
1729
+
1730
+ .offset-lg-1 {
1731
+ margin-left: 8.333333%
1732
+ }
1733
+
1734
+ .offset-lg-2 {
1735
+ margin-left: 16.666667%
1736
+ }
1737
+
1738
+ .offset-lg-3 {
1739
+ margin-left: 25%
1740
+ }
1741
+
1742
+ .offset-lg-4 {
1743
+ margin-left: 33.333333%
1744
+ }
1745
+
1746
+ .offset-lg-5 {
1747
+ margin-left: 41.666667%
1748
+ }
1749
+
1750
+ .offset-lg-6 {
1751
+ margin-left: 50%
1752
+ }
1753
+
1754
+ .offset-lg-7 {
1755
+ margin-left: 58.333333%
1756
+ }
1757
+
1758
+ .offset-lg-8 {
1759
+ margin-left: 66.666667%
1760
+ }
1761
+
1762
+ .offset-lg-9 {
1763
+ margin-left: 75%
1764
+ }
1765
+
1766
+ .offset-lg-10 {
1767
+ margin-left: 83.333333%
1768
+ }
1769
+
1770
+ .offset-lg-11 {
1771
+ margin-left: 91.666667%
1772
+ }
1773
+ }
1774
+
1775
+ @media (min-width: 1200px) {
1776
+ .col-xl {
1777
+ -ms-flex-preferred-size: 0;
1778
+ flex-basis: 0;
1779
+ -webkit-box-flex: 1;
1780
+ -ms-flex-positive: 1;
1781
+ flex-grow: 1;
1782
+ max-width: 100%
1783
+ }
1784
+
1785
+ .col-xl-auto {
1786
+ -webkit-box-flex: 0;
1787
+ -ms-flex: 0 0 auto;
1788
+ flex: 0 0 auto;
1789
+ width: auto;
1790
+ max-width: none
1791
+ }
1792
+
1793
+ .col-xl-1 {
1794
+ -webkit-box-flex: 0;
1795
+ -ms-flex: 0 0 8.333333%;
1796
+ flex: 0 0 8.333333%;
1797
+ max-width: 8.333333%
1798
+ }
1799
+
1800
+ .col-xl-2 {
1801
+ -webkit-box-flex: 0;
1802
+ -ms-flex: 0 0 16.666667%;
1803
+ flex: 0 0 16.666667%;
1804
+ max-width: 16.666667%
1805
+ }
1806
+
1807
+ .col-xl-3 {
1808
+ -webkit-box-flex: 0;
1809
+ -ms-flex: 0 0 25%;
1810
+ flex: 0 0 25%;
1811
+ max-width: 25%
1812
+ }
1813
+
1814
+ .col-xl-4 {
1815
+ -webkit-box-flex: 0;
1816
+ -ms-flex: 0 0 33.333333%;
1817
+ flex: 0 0 33.333333%;
1818
+ max-width: 33.333333%
1819
+ }
1820
+
1821
+ .col-xl-5 {
1822
+ -webkit-box-flex: 0;
1823
+ -ms-flex: 0 0 41.666667%;
1824
+ flex: 0 0 41.666667%;
1825
+ max-width: 41.666667%
1826
+ }
1827
+
1828
+ .col-xl-6 {
1829
+ -webkit-box-flex: 0;
1830
+ -ms-flex: 0 0 50%;
1831
+ flex: 0 0 50%;
1832
+ max-width: 50%
1833
+ }
1834
+
1835
+ .col-xl-7 {
1836
+ -webkit-box-flex: 0;
1837
+ -ms-flex: 0 0 58.333333%;
1838
+ flex: 0 0 58.333333%;
1839
+ max-width: 58.333333%
1840
+ }
1841
+
1842
+ .col-xl-8 {
1843
+ -webkit-box-flex: 0;
1844
+ -ms-flex: 0 0 66.666667%;
1845
+ flex: 0 0 66.666667%;
1846
+ max-width: 66.666667%
1847
+ }
1848
+
1849
+ .col-xl-9 {
1850
+ -webkit-box-flex: 0;
1851
+ -ms-flex: 0 0 75%;
1852
+ flex: 0 0 75%;
1853
+ max-width: 75%
1854
+ }
1855
+
1856
+ .col-xl-10 {
1857
+ -webkit-box-flex: 0;
1858
+ -ms-flex: 0 0 83.333333%;
1859
+ flex: 0 0 83.333333%;
1860
+ max-width: 83.333333%
1861
+ }
1862
+
1863
+ .col-xl-11 {
1864
+ -webkit-box-flex: 0;
1865
+ -ms-flex: 0 0 91.666667%;
1866
+ flex: 0 0 91.666667%;
1867
+ max-width: 91.666667%
1868
+ }
1869
+
1870
+ .col-xl-12 {
1871
+ -webkit-box-flex: 0;
1872
+ -ms-flex: 0 0 100%;
1873
+ flex: 0 0 100%;
1874
+ max-width: 100%
1875
+ }
includes/css/hide-login.css ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body.login-action-login div#login {
2
+ display: none;
3
+ }
4
+
5
+ body.login-action-login div#login form#loginform input#user_login {
6
+ display: none;
7
+ }
8
+
9
+ body.login-action-login div#login form#loginform p.forgetmenot {
10
+ display: none;
11
+ }
12
+
13
+ body.login-action-login div#login form#loginform p.submit input#wp-submit {
14
+ display: none;
15
+ }
16
+
17
+ body.login-action-login div#login form#loginform p label {
18
+ display: none;
19
+ }
20
+
21
+ body.login-action-login div#login p#nav {
22
+ display: none;
23
+ }
24
+
25
+ body.login-action-login div#login form#loginform input#user_pass {
26
+ display: none;
27
+ }
28
+
29
+ body.login-action-login div#login div#login_error {
30
+ display: none;
31
+ }
32
+
33
+ body.login-action-login p.message {
34
+ display: none;
35
+ }
36
+
37
+ body.login-action-login div#login #loginform {
38
+ box-shadow: inherit;
39
+ }
40
+
41
+ body.login-action-login div#login div#login_error1 {
42
+ border-left: 4px solid #dd3d36;
43
+ margin-left: 0;
44
+ padding: 12px;
45
+ background: #fff;
46
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
47
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
48
+ }
49
+
50
+ .mo2f_header {
51
+ font-size: 28px;
52
+ font-family: -webkit-body;
53
+ color: #777;
54
+ }
55
+
56
+ .mo2f_powered_by_miniorange {
57
+ width: 100px;
58
+ height: 25px;
59
+ -webkit-background-size: 100px 25px;
60
+ background-size: 100px 25px;
61
+ background-repeat: no-repeat;
62
+ display: inline-block;
63
+ vertical-align: middle;
64
+ }
65
+
66
+ .mo2f_powered_by_div {
67
+ text-align: right;
68
+ font-size: 9px;
69
+ padding-right: 2%;
70
+ background-color: #FFFFFF;
71
+ }
72
+
73
+ .button-green {
74
+ color: rgb(0, 160, 210);
75
+ background: none !important;
76
+ border: none;
77
+ padding: 0 !important;
78
+ font: inherit;
79
+ border-color: transparent !important;
80
+ /*border is optional*/
81
+ border-bottom: 1px solid #444;
82
+ cursor: pointer;
83
+ }
84
+
85
+ .mo2fa_display_message {
86
+ padding: 12px;
87
+ border-left: 4px solid #00a0d2;
88
+ background-color: #fff;
89
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);
90
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);
91
+
92
+ }
93
+
94
+ .mo2fa_messages_container {
95
+ width: 300px;
96
+ }
97
+
98
+ .mo2fa_otp_messages_container {
99
+ width: 400px;
100
+ }
101
+
102
+ .mo2fa_push_messages_container {
103
+ width: 300px;
104
+ }
105
+
106
+ .miniorange_mobile_auth, .miniorange_app_setup_page {
107
+ border: 1px none transparent;
108
+ padding: 10% 24px 10px 20px;
109
+ min-height: 360px;
110
+ background: transparent;
111
+ z-index: 99999;
112
+ }
113
+
114
+ .miniorange_kba_page {
115
+ border: 1px none transparent;
116
+ padding: 10% 24px 10px 20px;
117
+ min-height: 360px;
118
+ background: transparent;
119
+ z-index: 99999;
120
+
121
+ }
122
+
123
+ .miniorange_push_oobemail_auth, .miniorange_trust_device {
124
+ border: 1px none transparent;
125
+ padding: 10% 24px 10px 20px;
126
+ min-height: 360px;
127
+ background: transparent;
128
+ z-index: 99999;
129
+ }
130
+
131
+ .miniorange_soft_auth {
132
+ border: 1px none transparent;
133
+ padding: 10% 24px 10px 20px;
134
+ min-height: 360px;
135
+ background: transparent;
136
+ z-index: 99999;
137
+ }
138
+
139
+ .miniorange-inner-login-container {
140
+ background-color: #fff;
141
+ margin: 0px auto !important;
142
+ width: 400px;
143
+ border-radius: 5px;
144
+ border: 1px solid rgba(128, 128, 128, 0.06);
145
+ }
146
+
147
+ .miniorange-inner-kba-login-container {
148
+ background-color: #fff;
149
+ margin: 0px auto !important;
150
+ width: 500px;
151
+ border-radius: 5px;
152
+ z-index: 99999;
153
+ border: 1px solid rgba(128, 128, 128, 0.06);
154
+ }
155
+
156
+ .miniorange-inner-push-login-container {
157
+ background-color: #fff;
158
+ margin: 0px auto !important;
159
+ width: 300px;
160
+ border-radius: 5px;
161
+
162
+ z-index: 99999;
163
+ border: 1px solid rgba(128, 128, 128, 0.06);
164
+ }
165
+
166
+ .miniorange-button {
167
+ height: 30px;
168
+ display: inline-block;
169
+ font-size: 14px;
170
+ line-height: 28px;
171
+ padding: 0 12px 2px;
172
+ border-width: 1px;
173
+ vertical-align: baseline;
174
+ background: #00a0d2;
175
+ border-style: solid;
176
+ border-color: #0073aa;
177
+ -webkit-appearance: none;
178
+ -webkit-border-radius: 3px;
179
+ border-radius: 3px;
180
+ white-space: nowrap;
181
+ -webkit-box-sizing: border-box;
182
+ -moz-box-sizing: border-box;
183
+ box-sizing: border-box;
184
+ -webkit-box-shadow: inset 0 1px 0 rgba(120, 200, 230, .5), 0 1px 0 rgba(0, 0, 0, .15);
185
+ box-shadow: inset 0 1px 0 rgba(120, 200, 230, .5), 0 1px 0 rgba(0, 0, 0, .15);
186
+ color: #fff;
187
+ text-decoration: none;
188
+ cursor: pointer;
189
+ }
190
+
191
+ .mo_green {
192
+ background: #2ECC71;
193
+ border-color: #2ECC71;
194
+ width: 37%;
195
+ }
196
+
197
+ .mo_red {
198
+ background: #E74C3C;
199
+ border-color: #E74C3C;
200
+ width: 37%;
201
+ }
202
+
203
+ .showQRHelp, .showOTPHelp {
204
+ text-align: center !important;
205
+ }
206
+
207
+ .mo_email_textbox {
208
+ width: 48%;
209
+ text-align: center;
210
+ height: 40px;
211
+ font-size: 18px;
212
+ border-radius: 5px;
213
+ }
214
+
215
+ .mo_header_background {
216
+ padding: 5px !important;
217
+ background-color: beige !important;
218
+ }
219
+
220
+ .mo2f_textbox {
221
+ width: 60% !important;
222
+ border-radius: 4px !important;
223
+ height: 30px !important;
224
+ font-size: 14px !important;
225
+ }
226
+
227
+ .mo2f_kba_textbox {
228
+ width: 100% !important;
229
+ border-radius: 4px !important;
230
+ height: 30px !important;
231
+ font-size: 14px !important;
232
+ }
233
+
234
+ .mo_hr {
235
+ border-top: 1px solid rgba(220, 214, 214, 0.25) !important;
236
+ margin-top: 5px !important;
237
+ margin-right: 10px !important;
238
+ }
239
+
240
+ .mo_margin_left {
241
+ margin-left: 20px !important;
242
+ }
243
+
244
+ .miniorange-app-setup-container {
245
+ background-color: #fff;
246
+ margin: 0px auto !important;
247
+ width: 700px;
248
+ border-radius: 5px;
249
+ margin-top: -100px !important;
250
+ z-index: 99999;
251
+ border: 1px solid rgba(128, 128, 128, 0.06);
252
+
253
+ }
254
+
255
+ .miniorange-ga-setup-container {
256
+ background-color: #fff;
257
+ margin: 0px auto !important;
258
+ width: 900px;
259
+ border-radius: 5px;
260
+ margin-top: -50px !important;
261
+ z-index: 99999;
262
+ border: 1px solid rgba(128, 128, 128, 0.06);
263
+ }
264
+
265
+ .mo_app_link {
266
+ text-decoration: none !important;
267
+ color: #000 !important;
268
+ }
269
+
270
+ .mo2fa_app_setup_messages {
271
+ width: 700px;
272
+ }
273
+
274
+ .mo2f_td_show {
275
+ display: grid !important;
276
+ }
277
+
278
+ .mo2f_td_hide {
279
+ display: none !important;
280
+ }
281
+
282
+ .mo2f_kba_ques {
283
+ width: 370px !important;
284
+ border-radius: 4px !important;
285
+ height: 30px !important;
286
+ font-size: 14px !important;
287
+ }
288
+
289
+ .mo2f_kba_table {
290
+ padding: 0 10px;
291
+ width: 100%;
292
+ }
293
+
294
+ .mo2f_kba_tb_data {
295
+ padding-left: 15px;
296
+ }
297
+
298
+ .mo2f_table_textbox {
299
+ width: 150px;
300
+ height: 30px !important;
301
+ font-size: 14px !important;
302
+
303
+ }
304
+
305
+ .mo2f_kba_header {
306
+ font-weight: bold;
307
+ }
308
+
309
+ .mo2f_separator {
310
+ border-left: 1px solid #EBECEC;
311
+ padding: 5px;
312
+ }
313
+
314
+ .mo2f_inline_padding {
315
+ padding-left: 20px;
316
+ padding-right: 20px;
317
+ }
includes/css/style_settings.css CHANGED
@@ -1,3 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  .mo_wpns_help_title {
2
  font-size:17px;
3
  width:100%;
@@ -36,13 +115,27 @@
36
  .mo_wpns_tab {
37
  /*overflow: hidden;*/
38
  /*border: 1px solid #ccc;*/
 
 
 
39
  background-color: #f1f1f1;
40
- margin:22px;
41
- height: 31px;
 
 
 
 
 
 
 
 
 
 
42
  }
43
 
44
  /* Style the buttons inside the tab */
45
  .mo_wpns_tab button {
 
46
  background-color: inherit;
47
  float: left;
48
  outline: none;
@@ -119,7 +212,7 @@
119
  margin-bottom: 10px;
120
  margin-top: 10px;
121
  height:auto;
122
- width:74%;
123
  float:left;
124
 
125
 
@@ -1353,14 +1446,14 @@ h1 .nav-tab, div .nav-tab
1353
  background-color: white;
1354
  color:#20b2aa;
1355
  }
1356
- .ip_lookup_desc,.db_backup_desc{
1357
  background-color:#E6E6E6;
1358
  width:100%;
1359
  margin-top:1%;
1360
  padding:10px;
1361
  }
1362
 
1363
- .ip_lookup_desc img,.db_backup_desc img{
1364
  margin-left:45%;
1365
  }
1366
 
@@ -1801,11 +1894,11 @@ padding-right: 11px;
1801
  line-height: 20px; /* To center it vertically */
1802
  color: white;
1803
  }
1804
- #mo_wpns_bar {
1805
  width: 0%;
1806
  height: 20px;
1807
  background-color: blue;
1808
- }
1809
  .mo_wpns_lightgreen{
1810
  color:rgb(128, 173, 128);
1811
  }
@@ -2507,7 +2600,7 @@ a.mo2f_thumbnail:hover, a.mo2f_thumbnail:focus, a.mo2f_thumbnail.active {
2507
  border: 1px;
2508
  text-align: center;
2509
  text-decoration: none;
2510
-
2511
  font-size: 20px;
2512
  margin: 0px 0px;
2513
  cursor: pointer;
@@ -2527,7 +2620,7 @@ a.mo2f_thumbnail:hover, a.mo2f_thumbnail:focus, a.mo2f_thumbnail.active {
2527
  border: 1px;
2528
  text-align: center;
2529
  text-decoration: none;
2530
- display: inline-table;
2531
  font-size: 17px;
2532
  margin: 0px 0px;
2533
  cursor: pointer;
@@ -2623,1488 +2716,24 @@ a.mo2f_thumbnail:hover, a.mo2f_thumbnail:focus, a.mo2f_thumbnail.active {
2623
  margin: -4px 2px;
2624
  cursor: pointer;
2625
  }
2626
- /*2FA css*/
2627
-
2628
- /*
2629
-
2630
- .impt {
2631
- color: #FF0000
2632
- }
2633
-
2634
- .mo2f_container{
2635
- margin-left: -1%;
2636
- width: 100%;
2637
- }
2638
-
2639
- .mo2f_small_layout {
2640
- background-color: #FFFFFF;
2641
- border: 1px solid #CCCCCC;
2642
- padding: 0px 24px 10px 20px;
2643
- }
2644
-
2645
- .mo2f_help_layout {
2646
- background-color: #FFFFFF;
2647
- border: 1px solid #CCCCCC;
2648
- padding-left: 20px;
2649
- min-height: 550px;
2650
- }
2651
-
2652
- .mo2f_table_layout td strong {
2653
- margin-left: 10px;
2654
- }
2655
-
2656
- .col1 {
2657
- width: 20%;
2658
- }
2659
-
2660
- #panel1 {
2661
- width: 100%;
2662
- }
2663
-
2664
- .panel_toggle {
2665
- cursor: pointer;
2666
- }
2667
-
2668
- .panel_toggle:hover {
2669
- text-decoration: underline;
2670
- }
2671
- .mo2f_settings_table {
2672
- width: 100%;
2673
- }
2674
-
2675
- #mo2f_note {
2676
- background-color: #d9edf7;
2677
- border-radius: 4px;
2678
- padding: 5px;
2679
- color: #31708f;
2680
- font-style: italic;
2681
- }
2682
-
2683
- .button-green {
2684
- background: #95D387 !important;
2685
- color: #ffffff !important;
2686
- border: 1px solid #95D387 !important;
2687
- }
2688
-
2689
- .mo2f_user_layout {
2690
- margin-top: 20px;
2691
- margin-right: 20px;
2692
- }
2693
-
2694
- .header2 {
2695
- font-size: 1.6em;
2696
- color: #00A0D2;
2697
- }
2698
-
2699
- .alert-box {
2700
- margin-top: 21px;
2701
- }
2702
-
2703
- .extra-large {
2704
- padding: 10px !important;
2705
- font-size: 2em !important;
2706
- height: 46px !important;
2707
- border-radius: 5px !important;
2708
- line-height: 25px !important;
2709
- }
2710
-
2711
- .mo2f_account_header {
2712
- margin: 0px !important;
2713
-
2714
- }
2715
-
2716
- a {
2717
- text-decoration: none !important;
2718
-
2719
- }
2720
-
2721
- .mo2f_help_container {
2722
- background-color: #ccc !important;
2723
- }
2724
-
2725
- .mo2f_faqs > h3, .mo2f_faqs > div {
2726
- margin-left: 15px !important;
2727
- margin-right: 5px !important;
2728
-
2729
- }
2730
-
2731
- .mo2f_faqs > div {
2732
- padding: 5px 20px !important;
2733
- border-left: 2px solid grey;
2734
- }
2735
-
2736
- .mo2f_faqs > hr {
2737
- border-top: 1px solid rgb(135, 129, 129) !important;
2738
- margin-right: 20px !important;
2739
- }
2740
-
2741
- .mo2f_faqs > h3 > a:focus {
2742
- box-shadow: 0px 0px 0px 0px #fff !important;
2743
- }
2744
-
2745
- .mo2f_msgs {
2746
- font-size: 14px !important;
2747
- }
2748
-
2749
- .mo2f_row {
2750
-
2751
- display: -webkit-inline-box !important;
2752
- }
2753
-
2754
- .color-icon {
2755
- vertical-align: middle;
2756
- display: inline-block;
2757
- width: 15px;
2758
- height: 15px;
2759
- margin-left: 20px;
2760
- }
2761
-
2762
- .activeMethod {
2763
- background-color: rgba(99, 143, 223, 0.42) !important;
2764
- margin-left: 23%;
2765
-
2766
- }
2767
-
2768
- .inactiveMethod {
2769
- background-color: rgba(221, 221, 221, 0.66) !important;
2770
- margin-left: 20.5%;
2771
-
2772
- }
2773
-
2774
- .configuredLaptop {
2775
- background: url(../images/laptop-24.png) rgba(99, 143, 223, 0.42) no-repeat right;
2776
- padding: 10px;
2777
- margin-bottom: 0px;
2778
- }
2779
-
2780
- .notConfiguredLaptop {
2781
- background: url(../images/laptop-24.png) rgba(221, 221, 221, 0.66) no-repeat right;
2782
- padding: 20px;
2783
- margin-bottom: 0px;
2784
- }
2785
-
2786
- .mo2f_column_padding {
2787
- padding-right: 10px;
2788
-
2789
- }
2790
-
2791
- .mo2f_td_show {
2792
- display: table-cell;
2793
- }
2794
-
2795
- .mo2f_td_hide {
2796
- display: none !important;
2797
- }
2798
-
2799
- .mo2f_pricing_table {
2800
- text-align: center;
2801
- font-size: 15px !important;
2802
- }
2803
-
2804
- .mo2f_pricing_header {
2805
- color: #fff !important;
2806
- margin: 8px !important;
2807
- }
2808
-
2809
- .mo2f_pricing_sub_header {
2810
- margin: 4px !important;
2811
- color: #fff !important;
2812
- }
2813
-
2814
- .mo2f_pricing_text {
2815
- font-size: 15px !important;
2816
- color: #fff !important;
2817
- font-weight: bold !important;
2818
- }
2819
-
2820
- .mo2f_pricing_free_tab {
2821
- background-color: rgba(34, 153, 221, 0.82) !important;
2822
- }
2823
-
2824
- .mo2f_pricing_paid_tab {
2825
- background-color: #1a71a4 !important;
2826
- }
2827
-
2828
-
2829
-
2830
- .mo2f_auth_methods_thumbnail {
2831
- width: 50px;
2832
- height: 50px;
2833
- padding: 20px;
2834
- line-height: 80px;
2835
- }
2836
-
2837
- .mo2f_auth_method_title {
2838
- font-size: 15px;
2839
- font-weight: bold;
2840
- }
2841
-
2842
- .mo_table-bordered, .mo_table-bordered > tbody > tr > td {
2843
- border: 1px solid #ddd;
2844
- }
2845
-
2846
- .mo_table-striped > tbody > tr:nth-of-type(odd) {
2847
- background-color: #f9f9f9;
2848
- }
2849
-
2850
- .mo_table-bordered > thead > tr > th {
2851
- vertical-align: top !important;
2852
- }
2853
-
2854
- .mo_plan-desc {
2855
- font-size: 14px !important;
2856
- }
2857
-
2858
- .mo_align-center > tr > td {
2859
- text-align: center !important;
2860
- }
2861
-
2862
- .mo-fa-icon > tr > td > i.fa {
2863
- color: #5b8a0f;
2864
-
2865
- }
2866
-
2867
- .dropbtn {
2868
- background-color: #4CAF50;
2869
- color: white;
2870
- padding: 16px;
2871
- font-size: 16px;
2872
- border: none;
2873
- cursor: pointer;
2874
- border-radius: 5px;
2875
- }
2876
-
2877
- .dropdown {
2878
- position: relative;
2879
- display: inline-block;
2880
-
2881
- }
2882
-
2883
- .dropdown-content {
2884
- display: none;
2885
- position: absolute;
2886
- background-color: #f9f9f9;
2887
- min-width: 160px;
2888
- box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
2889
- z-index: 9999;
2890
- }
2891
-
2892
- .dropdown-content a {
2893
- color: black;
2894
- padding: 12px 16px;
2895
- text-decoration: none;
2896
- display: block;
2897
- }
2898
-
2899
- .dropdown-content a:hover {
2900
- background-color: #f1f1f1
2901
- }
2902
-
2903
- .dropdown:hover .dropdown-content {
2904
- display: block;
2905
- }
2906
-
2907
- .dropdown:hover .dropbtn {
2908
- background-color: #3e8e41;
2909
- }
2910
-
2911
- /* added by gayathri */
2912
-
2913
- /*
2914
-
2915
- .mo2f_vertical_line {
2916
- border-left: 1px solid #EBECEC;
2917
- padding: 5px
2918
- }
2919
-
2920
- .mo2f_ol li {
2921
- padding: 1px;
2922
- }
2923
-
2924
- .mo2f_google_authy_secret_outer_div {
2925
- padding: 10px;
2926
- background-color: #f9edbe;
2927
- width: 20em;
2928
- text-align: center;
2929
- }
2930
-
2931
- .mo2f_google_authy_secret_text {
2932
- font-size: 80%;
2933
- color: #666666;
2934
- }
2935
-
2936
- .mo2f_google_authy_secret_inner_div {
2937
- font-size: 14px;
2938
- font-weight: bold;
2939
- line-height: 1.5;
2940
- }
2941
-
2942
- .mo2f_backup_options, .kbaSectiondiv {
2943
- padding-left: 10px;
2944
- padding-right: 10px;
2945
- }
2946
-
2947
- .mo2f_backup_options_div {
2948
- padding-left: 10px;
2949
- padding-right: 40px;
2950
  }
 
2951
 
2952
- .mo2f_rememberdevice {
2953
- float: left;
2954
- font-size: 15px;
2955
- padding-right: 10px;
2956
  }
 
 
 
 
 
2957
 
2958
- .mo2f_trust_device {
2959
- vertical-align: text-top;
2960
  }
2961
-
2962
- .mo2f_push_oob_message {
2963
- font-size: 16px;
2964
- font-weight: bold;
2965
- color: #34495E;
2966
- }
2967
-
2968
- .mo2f_login_prompt_messages {
2969
- font-size: 16px;
2970
- font-weight: bold;
2971
- color: #2980B9;
2972
-
2973
- }
2974
-
2975
- .mo2f_display_none_forms {
2976
- display: none
2977
- }
2978
-
2979
- .mo2f_licensing_plans {
2980
- background-color: white;
2981
- border-style: solid;
2982
- border-color: lightgrey;
2983
- border-radius: 4px;
2984
- border-width: 1px;
2985
- padding: 10px;
2986
- }
2987
-
2988
- .mo2f_licensing_plans_tr {
2989
- background-color: #bbccdd;
2990
- }
2991
-
2992
- .mo2f_licensing_plans_plan_desc {
2993
- color: white;
2994
- font-size: 16px
2995
- }
2996
-
2997
- .mo2f_licensing_plans_ol {
2998
- margin-left: 3%
2999
- }
3000
-
3001
- .mo2f_container_views {
3002
- background-color: white;
3003
- border-style: solid;
3004
- border-color: lightgray;
3005
- border-width: 1px;
3006
- border-radius: 2px;
3007
- padding: 20px;
3008
- min-height: 400px;
3009
- }
3010
-
3011
- .mo2f_register_with_mo_message {
3012
- display: block;
3013
- color: red;
3014
- background-color: rgba(251, 232, 0, 0.15);
3015
- padding: 5px;
3016
- border: solid 1px rgba(255, 0, 9, 0.36)
3017
- }
3018
-
3019
- .mo2f_advanced_options_outer_div {
3020
- background-color: white;
3021
- border-style: solid;
3022
- border-color: lightgrey;
3023
- border-radius: 4px;
3024
- border-width: 1px;
3025
- padding: 20px;
3026
- align-content: center
3027
- }
3028
-
3029
- .mo2f_advanced_options {
3030
- font-family: 'Segoe UI';
3031
- background-color: white;
3032
- min-width: 750px;
3033
- padding: 5px;
3034
- }
3035
-
3036
- .mo2f_advanced_options_div {
3037
- font-family: 'Segoe UI';
3038
- background-color: white;
3039
- border-color: #CACFD2;
3040
- min-height: 350px;
3041
- border-style: solid;
3042
- border-width: 2px;
3043
- padding: 20px;
3044
- }
3045
-
3046
- .mo2f_advanced_options_note {
3047
- background-color: #bbccdd;
3048
- border-radius: 2px;
3049
- }
3050
-
3051
- .mo2f_advanced_options_a {
3052
- cursor: pointer;
3053
- font-size: 15px;
3054
- color: #333;
3055
- font-weight: bold;
3056
- }
3057
-
3058
- .mo2f_advanced_options_EC {
3059
- background-color: white;
3060
- border-style: solid;
3061
- border-color: lightgrey;
3062
- border-radius: 4px;
3063
- border-width: 1px;
3064
- padding: 30px;
3065
- width: 700px;
3066
- align-content: center
3067
-
3068
- }
3069
-
3070
- #step1_skip, #step2_skip, #step3_skip, #step5_skip_test, #step4_skip_test {
3071
- float: left;
3072
- }
3073
-
3074
- .mo2f_advanced_options_a {
3075
- font-family: "Segoe UI";;
3076
- padding: 20px;
3077
- font-weight: bold;
3078
- font-size: medium;
3079
- color: black
3080
- }
3081
-
3082
- .mo2f_advanced_options_a:hover {
3083
- curosr: pointer
3084
- }
3085
-
3086
- .mo2f_pointer {
3087
- cursor: pointer;
3088
- }
3089
-
3090
- .mo2f_addon_spacing {
3091
- margin-left: 1%;
3092
- padding: 1px 16px;
3093
- }
3094
-
3095
- .mo2f_std_prem_p {
3096
- font-size: 20px;
3097
- font-family: Segoe UI;
3098
- color: darkblue;
3099
- }
3100
-
3101
- .mo2f_push_oob_backup {
3102
- font-size: 17px;
3103
- font-family: Segoe UI;
3104
- color: cornflowerblue;
3105
- }
3106
-
3107
- .twofa-license {
3108
- background-color: orange !important;
3109
- color: #000 !important
3110
- }
3111
-
3112
- .twofa-license:hover {
3113
- color: #fff !important;
3114
- border-color: #c28f37 !important
3115
- }
3116
-
3117
- /* The alert message box */
3118
- /*
3119
- .alert {
3120
- font-style: italic;
3121
- padding: 10px;
3122
- background-color: yellowgreen;
3123
- color: white;
3124
- margin-bottom: 15px;
3125
- border-radius:5px;
3126
- }
3127
-
3128
- /* The close button */
3129
- /*
3130
- .closebtn {
3131
- margin-left: 15px;
3132
- color: white;
3133
- font-weight: bold;
3134
- float: right;
3135
- font-size: 22px;
3136
- line-height: 10px;
3137
- cursor: pointer;
3138
- height: 8px;
3139
- transition: 0.3s;
3140
- }
3141
-
3142
- /* When moving the mouse over the close button */
3143
- /*
3144
- .closebtn:hover {
3145
- color: black;
3146
- }
3147
-
3148
- .impt {
3149
- color: #FF0000
3150
- }
3151
-
3152
- .mo2f_small_layout {
3153
- background-color: #FFFFFF;
3154
- border: 1px solid #CCCCCC;
3155
- padding: 0px 24px 10px 20px;
3156
- }
3157
-
3158
- .mo2f_support_layout {
3159
- width: 40%;
3160
- height: 78%;
3161
- background-color: #FFFFFF;
3162
- padding: 0px 24px 0px 20px;
3163
- display: none;
3164
- position: fixed;
3165
- bottom: 14%;
3166
- right: 15px;
3167
- z-index: 99999;
3168
- border-radius: 6px;
3169
- }
3170
-
3171
- .mo2f_help_layout {
3172
- background-color: #FFFFFF;
3173
- border: 1px solid #CCCCCC;
3174
- padding-left: 20px;
3175
- min-height: 550px;
3176
- }
3177
-
3178
- .mo2f_table_layout td strong {
3179
- margin-left: 10px;
3180
- }
3181
-
3182
- .col1 {
3183
- width: 20%;
3184
- }
3185
-
3186
- #panel1 {
3187
- width: 100%;
3188
- }
3189
-
3190
- .panel_toggle {
3191
- cursor: pointer;
3192
- }
3193
-
3194
- .panel_toggle:hover {
3195
- text-decoration: underline;
3196
- }
3197
-
3198
- .mo2f_authy_step1 {
3199
- vertical-align: top;
3200
- padding-right: 15px;
3201
- width: 26%;
3202
- }
3203
-
3204
- .mo2f_authy_step2 {
3205
- vertical-align: top;
3206
- padding-right: 15px;
3207
- width: 46%;
3208
- }
3209
-
3210
- .mo2f_table_textbox {
3211
- width: 100%;
3212
- height: 30px;
3213
- }
3214
-
3215
- .mo2f_settings_table {
3216
- width: 100%;
3217
- }
3218
-
3219
- #mo2f_note {
3220
- background-color: #d9edf7;
3221
- border-radius: 4px;
3222
- padding: 5px;
3223
- color: #31708f;
3224
- font-style: italic;
3225
- }
3226
-
3227
- .button-green {
3228
- background: #95D387 !important;
3229
- color: #ffffff !important;
3230
- border: 1px solid #95D387 !important;
3231
- }
3232
-
3233
- .mo2f_user_layout {
3234
- margin-top: 20px;
3235
- margin-right: 20px;
3236
- }
3237
-
3238
- .header2 {
3239
- font-size: 1.6em;
3240
- color: #00A0D2;
3241
- }
3242
-
3243
- .alert-box {
3244
- margin-top: 21px;
3245
- }
3246
-
3247
- .extra-large {
3248
- padding: 10px !important;
3249
- font-size: 2em !important;
3250
- height: 46px !important;
3251
- border-radius: 5px !important;
3252
- line-height: 25px !important;
3253
- }
3254
-
3255
- .mo2f_account_header {
3256
- margin: 0px !important;
3257
-
3258
- }
3259
-
3260
- a {
3261
- text-decoration: none !important;
3262
-
3263
- }
3264
-
3265
- .mo2f_help_container {
3266
- background-color: #ccc !important;
3267
- }
3268
-
3269
- .mo2f_faqs > h3, .mo2f_faqs > div {
3270
- margin-left: 15px !important;
3271
- margin-right: 5px !important;
3272
-
3273
- }
3274
-
3275
- .mo2f_faqs > div {
3276
- padding: 5px 20px !important;
3277
- border-left: 2px solid grey;
3278
- }
3279
-
3280
- .mo2f_faqs > hr {
3281
- border-top: 1px solid rgb(135, 129, 129) !important;
3282
- margin-right: 20px !important;
3283
- }
3284
-
3285
- .mo2f_faqs > h3 > a:focus {
3286
- box-shadow: 0px 0px 0px 0px #fff !important;
3287
- }
3288
-
3289
- .mo2f_msgs {
3290
- font-size: 14px !important;
3291
- }
3292
-
3293
- .mo2f_row {
3294
-
3295
- display: -webkit-inline-box !important;
3296
- }
3297
-
3298
- .configuredBasic {
3299
- background: url(../images/feat_smart.png) rgba(99, 143, 223, 0.42) no-repeat right;
3300
- padding: 10px;
3301
- margin-bottom: 0px;
3302
- }
3303
-
3304
- .configuredSmart {
3305
- background: url(../images/Smartphone-24.png) rgba(99, 143, 223, 0.42) no-repeat right;
3306
- padding: 10px;
3307
- margin-bottom: 0px;
3308
- }
3309
-
3310
- .notConfiguredBasic {
3311
- background: url(../images/feat_smart.png) rgba(221, 221, 221, 0.66) no-repeat right;
3312
- padding: 10px;
3313
- margin-bottom: 0px;
3314
- }
3315
-
3316
- .notConfiguredSmart {
3317
- background: url(../images/Smartphone-24.png) rgba(221, 221, 221, 0.66) no-repeat right;
3318
- padding: 10px;
3319
- margin-bottom: 0px;
3320
- }
3321
-
3322
- .configuredLandline {
3323
- background: url(../images/landline_sprite.png) rgba(99, 143, 223, 0.42) no-repeat right;
3324
- padding: 10px;
3325
- margin-bottom: 0px;
3326
- }
3327
-
3328
- .notConfiguredLandline {
3329
- background: url(../images/landline_sprite.png) rgba(221, 221, 221, 0.66) no-repeat right;
3330
- padding: 10px;
3331
- margin-bottom: 0px;
3332
- }
3333
-
3334
- .selectedMethod {
3335
- background-color: rgba(54, 157, 4, 0.42) !important;
3336
- }
3337
-
3338
- .color-icon {
3339
- vertical-align: middle;
3340
- display: inline-block;
3341
- width: 15px;
3342
- height: 15px;
3343
- margin-left: 20px;
3344
- }
3345
-
3346
- .activeMethod {
3347
- background-color: rgba(99, 143, 223, 0.42) !important;
3348
- margin-left: 23%;
3349
-
3350
- }
3351
-
3352
- .mo2f_column_padding {
3353
- padding-right: 10px;
3354
-
3355
- }
3356
-
3357
- .mo2f_td_show {
3358
- display: table-cell;
3359
- }
3360
-
3361
- .mo2f_td_hide {
3362
- display: none !important;
3363
- }
3364
-
3365
- .mo2f_pricing_table {
3366
- text-align: center;
3367
- font-size: 15px !important;
3368
- }
3369
-
3370
- .mo2f_pricing_header {
3371
- color: #fff !important;
3372
- margin: 8px !important;
3373
- }
3374
-
3375
- .mo2f_pricing_sub_header {
3376
- margin: 4px !important;
3377
- color: #fff !important;
3378
- }
3379
-
3380
- .mo2f_pricing_text {
3381
- font-size: 15px !important;
3382
- color: #fff !important;
3383
- font-weight: bold !important;
3384
- }
3385
-
3386
- .mo2f_pricing_free_tab {
3387
- background-color: rgba(34, 153, 221, 0.82) !important;
3388
- }
3389
-
3390
- .mo2f_pricing_paid_tab {
3391
- background-color: #1a71a4 !important;
3392
- }
3393
-
3394
- .mo2f_kba_ques {
3395
- width: 412px !important;
3396
- border-radius: 4px;
3397
- height: 30px;
3398
- font-size: 13px !important;
3399
- }
3400
-
3401
- .mo2f_kba_table {
3402
- padding-left: 10px;
3403
- width: 80%;
3404
- }
3405
-
3406
- .mo2f_kba_tb_data {
3407
- padding-left: 80px;
3408
- }
3409
-
3410
- .mo2f_grayed_out {
3411
- background-color: rgba(128, 128, 128, 0.05) !important;
3412
- opacity: .5;
3413
- }
3414
-
3415
- .mo2f_grayed_out_link {
3416
- position: absolute;
3417
- float: right;
3418
- margin: 0.5% 0 0 24%;
3419
- z-index: 99;
3420
- }
3421
-
3422
- .black_overlay {
3423
- display: none;
3424
- position: absolute;
3425
- top: 0%;
3426
- left: 0%;
3427
- width: 100%;
3428
- height: 100%;
3429
- background-color: black;
3430
- z-index: 1001;
3431
- -moz-opacity: 0.8;
3432
- opacity: .80;
3433
- filter: alpha(opacity=80);
3434
- }
3435
-
3436
- .mo2f_advanced_options_images {
3437
- display: inline-block;
3438
- padding: 15px;
3439
- width: 20px;
3440
- height: 20px;
3441
- float: left
3442
- }
3443
-
3444
- .mo2f_view_premium_plan_auth_methods, .mo2f_view_standard_plan_auth_methods, .mo2f_view_backup_options, .mo2f_view_backup_options_prem,
3445
- .mo2f_view_login_options, .mo2f_view_inline_registration_options, .mo2f_view_customizations, .mo2f_advanced_options_a,
3446
- .mo2f_view_customizations_prem {
3447
- color: navy;
3448
- cursor: pointer;
3449
- }
3450
-
3451
- .mo2f_view_free_plan_auth_methods {
3452
- color: black;
3453
- cursor: pointer;
3454
- }
3455
-
3456
- .mo2f_view_free_plan_auth_methods:hover {
3457
- color: black;
3458
- }
3459
-
3460
- .mo2f_view_premium_plan_auth_methods:hover, .mo2f_view_standard_plan_auth_methods:hover, .mo2f_view_backup_options:hover,
3461
- .mo2f_view_backup_options_prem:hover, .mo2f_view_customizations_prem:hover, .mo2f_view_login_options:hover, .mo2f_view_inline_registration_options:hover, .mo2f_view_customizations:hover {
3462
- color: limegreen;
3463
- }
3464
-
3465
- .mo2f_heading_style {
3466
- font-size: 18px;
3467
- font-family: Segoe UI;
3468
- padding: 11px;
3469
- }
3470
-
3471
- .mo2f_auth_methods_table {
3472
- border-spacing: 15px;
3473
- border-collapse: separate;
3474
- }
3475
-
3476
- .mo2f_auth_method_title {
3477
- font-size: 15px;
3478
- font-weight: bold;
3479
- }
3480
-
3481
- .mo2f_configure_2_factor {
3482
- padding: 10px;
3483
- float: left;
3484
- line-height: 20px;
3485
- }
3486
-
3487
- .mo2f_set_2_factor {
3488
- padding: 10px;
3489
- float: right;
3490
- line-height: 20px;
3491
- }
3492
-
3493
- .mo2f_configure_set_2_factor {
3494
- background-color: Transparent;
3495
- background-repeat: no-repeat;
3496
- border: none;
3497
- cursor: pointer;
3498
- overflow: hidden;
3499
- outline: none;
3500
- color: white;
3501
- }
3502
-
3503
- .mo2f_configure_set_2_factor:hover {
3504
- font-weight: bold;
3505
- font-size: 14px;
3506
- }
3507
-
3508
- .mo_table-bordered, .mo_table-bordered > tbody > tr > td {
3509
- border: 1px solid #ddd;
3510
- }
3511
-
3512
- .mo_table-striped > tbody > tr:nth-of-type(odd) {
3513
- background-color: #f9f9f9;
3514
- }
3515
-
3516
- .mo_table-bordered > thead > tr > th {
3517
- vertical-align: top !important;
3518
- }
3519
-
3520
- .mo_plan-desc {
3521
- font-size: 14px !important;
3522
- }
3523
-
3524
- .mo_align-center > tr > td {
3525
- text-align: center !important;
3526
- }
3527
-
3528
- .mo-fa-icon > tr > td > i.fa {
3529
- color: #5b8a0f;
3530
-
3531
- }
3532
-
3533
- .dropbtn {
3534
- background-color: #4CAF50;
3535
- color: white;
3536
- padding: 16px;
3537
- font-size: 16px;
3538
- border: none;
3539
- cursor: pointer;
3540
- border-radius: 5px;
3541
- }
3542
-
3543
- .dropdown {
3544
- position: relative;
3545
- display: inline-block;
3546
-
3547
- }
3548
-
3549
- .dropdown-content {
3550
- display: none;
3551
- position: absolute;
3552
- background-color: #f9f9f9;
3553
- min-width: 160px;
3554
- box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
3555
- z-index: 1;
3556
- }
3557
-
3558
- .dropdown-content a {
3559
- color: black;
3560
- padding: 12px 16px;
3561
- text-decoration: none;
3562
- display: block;
3563
- }
3564
-
3565
- .dropdown-content a:hover {
3566
- background-color: #f1f1f1
3567
- }
3568
-
3569
- .dropdown:hover .dropdown-content {
3570
- display: block;
3571
- }
3572
-
3573
- .dropdown:hover .dropbtn {
3574
- background-color: #3e8e41;
3575
- }
3576
-
3577
- /* added by gayathri */
3578
-
3579
- /*.mo2f_google_authy_step2 {
3580
- vertical-align: top;
3581
- padding-right: 15px;
3582
- width: 70%;
3583
- }
3584
-
3585
- .mo2f_google_authy_step3 {
3586
- vertical-align: top;
3587
- width: 30%
3588
- }
3589
-
3590
- .mo2f_vertical_line {
3591
- border-left: 1px solid #EBECEC;
3592
- padding: 5px
3593
- }
3594
-
3595
- .mo2f_ol li {
3596
- padding: 1px;
3597
- }
3598
-
3599
- .mo2f_google_authy_secret_outer_div {
3600
- padding: 10px;
3601
- background-color: #f9edbe;
3602
- width: 20em;
3603
- text-align: center;
3604
- }
3605
-
3606
- .mo2f_google_authy_secret_text {
3607
- font-size: 80%;
3608
- color: #666666;
3609
- }
3610
-
3611
- .mo2f_google_authy_secret_inner_div {
3612
- font-size: 14px;
3613
- font-weight: bold;
3614
- line-height: 1.5;
3615
- }
3616
-
3617
- .mo2f_backup_options, .kbaSectiondiv {
3618
- padding-left: 10px;
3619
- padding-right: 10px;
3620
- }
3621
-
3622
- .mo2f_backup_options_div {
3623
- padding-left: 10px;
3624
- padding-right: 40px;
3625
- }
3626
-
3627
- .mo2f_rememberdevice {
3628
- float: left;
3629
- font-size: 15px;
3630
- padding-right: 10px;
3631
- }
3632
-
3633
- .mo2f_trust_device {
3634
- vertical-align: text-top;
3635
- }
3636
-
3637
- .mo2f_push_oob_message {
3638
- font-size: 16px;
3639
- font-weight: bold;
3640
- color: #34495E;
3641
- }
3642
-
3643
- .mo2f_login_prompt_messages {
3644
- font-size: 16px;
3645
- font-weight: bold;
3646
- color: #2980B9;
3647
-
3648
- }
3649
-
3650
- .mo2f_display_none_forms {
3651
- display: none
3652
- }
3653
-
3654
- .mo2f_licensing_plans {
3655
- background-color: white;
3656
- border-style: solid;
3657
- border-color: lightgrey;
3658
- border-radius: 4px;
3659
- border-width: 1px;
3660
- padding: 10px;
3661
- }
3662
-
3663
- .mo2f_licensing_plans_tr {
3664
- background-color: #bbccdd;
3665
- }
3666
-
3667
- .mo2f_licensing_plans_plan_desc {
3668
- color: white;
3669
- font-size: 16px
3670
- }
3671
-
3672
- .mo2f_licensing_plans_ol {
3673
- margin-left: 3%
3674
- }
3675
-
3676
- .mo2f_container_views {
3677
- background-color: white;
3678
- border-style: solid;
3679
- border-color: lightgray;
3680
- border-width: 1px;
3681
- border-radius: 2px;
3682
- padding: 20px;
3683
- min-height: 400px;
3684
- }
3685
-
3686
- .mo2f_register_with_mo_message {
3687
- display: block;
3688
- color: red;
3689
- background-color: rgba(251, 232, 0, 0.15);
3690
- padding: 5px;
3691
- border: solid 1px rgba(255, 0, 9, 0.36)
3692
- }
3693
-
3694
- .mo2f_advanced_options_outer_div {
3695
- background-color: white;
3696
- border-style: solid;
3697
- border-color: lightgrey;
3698
- border-radius: 4px;
3699
- border-width: 1px;
3700
- padding: 20px;
3701
- align-content: center
3702
- }
3703
-
3704
- .mo2f_advanced_options {
3705
- font-family: 'Segoe UI';
3706
- background-color: white;
3707
- min-width: 750px;
3708
- padding: 5px;
3709
- }
3710
-
3711
- .mo2f_advanced_options_div {
3712
- font-family: 'Segoe UI';
3713
- background-color: white;
3714
- border-color: #CACFD2;
3715
- min-height: 350px;
3716
- border-style: solid;
3717
- border-width: 2px;
3718
- padding: 20px;
3719
- }
3720
-
3721
- .mo2f_advanced_options_note {
3722
- background-color: #bbccdd;
3723
- border-radius: 2px;
3724
- }
3725
-
3726
- .mo2f_advanced_options_a {
3727
- cursor: pointer;
3728
- font-size: 15px;
3729
- color: #333;
3730
- font-weight: bold;
3731
- }
3732
-
3733
- .mo2f_advanced_options_EC {
3734
- background-color: white;
3735
- border-style: solid;
3736
- border-color: lightgrey;
3737
- border-radius: 4px;
3738
- border-width: 1px;
3739
- padding: 30px;
3740
- width: 700px;
3741
- align-content: center
3742
-
3743
- }
3744
-
3745
- .mo2f_proxy_setup {
3746
- background-color: white;
3747
- padding: 30px;
3748
- align-content: center;
3749
- border:0px;
3750
-
3751
- }
3752
-
3753
- .mo2f_setup_2_factor_tab {
3754
- background-color: white;
3755
- border-style: solid;
3756
- border-color: lightgrey;
3757
- padding: 20px;
3758
- width: 93% !important;
3759
- align-content: center;
3760
- border: 0px;
3761
-
3762
- }
3763
-
3764
- #step1_skip, #step2_skip, #step3_skip, #step5_skip_test, #step4_skip_test {
3765
- float: left;
3766
- }
3767
-
3768
- .mo2f_advanced_options_a {
3769
- font-family: "Segoe UI";;
3770
- padding: 20px;
3771
- font-weight: bold;
3772
- font-size: medium;
3773
- color: black
3774
- }
3775
-
3776
-
3777
- .mo2f_advanced_options_a:hover {
3778
- curosr: pointer
3779
- }
3780
-
3781
- .mo2f_vertical-submenu {
3782
- margin: 0;
3783
- padding: 0;
3784
- width: 117%;
3785
- border-spacing: auto;
3786
- cursor: pointer;
3787
-
3788
- }
3789
-
3790
- .mo2f_vertical-submenu a {
3791
- display: inline;
3792
- background-color: #cce;
3793
- color: black;
3794
- margin-left: 6px;
3795
- width: 28%;
3796
- margin-top: 15px;
3797
- text-decoration: none;
3798
- text-align: center;
3799
- padding: 11px;
3800
- }
3801
-
3802
- .mo2f_vertical-submenu a:hover {
3803
- background-color: #ccc;
3804
- }
3805
-
3806
- .mo2f_vertical-submenu a.active {
3807
- background-color: #4CAF50;
3808
- color: white;
3809
- }
3810
-
3811
- .mo2f_box {
3812
- border: 1px solid #DCDCDC;
3813
- padding: 20px;
3814
- }
3815
-
3816
- .mo2f_pointer {
3817
- cursor: pointer;
3818
- }
3819
-
3820
- .mo2f_addon_spacing {
3821
- margin-left: 1%;
3822
- padding: 1px 16px;
3823
- }
3824
-
3825
- .mo2f_std_prem_p {
3826
- font-size: 20px;
3827
- font-family: Segoe UI;
3828
- color: darkblue;
3829
- }
3830
-
3831
- .mo2f_push_oob_backup {
3832
- font-size: 17px;
3833
- font-family: Segoe UI;
3834
- color: cornflowerblue;
3835
- }
3836
-
3837
- .add-new-h2 {
3838
- margin-left: 4px;
3839
- padding: 4px 8px;
3840
- position: relative;
3841
- top: -3px;
3842
- text-decoration: none;
3843
- border: none;
3844
- border: 1px solid #ccc;
3845
- border-radius: 2px;
3846
- background: #f7f7f7;
3847
- text-shadow: none;
3848
- font-weight: 600;
3849
- font-size: 13px;
3850
- line-height: normal;
3851
- color: #0073aa;
3852
- cursor: pointer;
3853
- outline: 0
3854
- }*/
3855
-
3856
- /*.twofa-license {
3857
- background-color: orange !important;
3858
- color: #000 !important
3859
- }
3860
-
3861
- .twofa-license:hover {
3862
- color: #fff !important;
3863
- border-color: #c28f37 !important
3864
- }
3865
-
3866
- .closebtn {
3867
- margin-left: 15px;
3868
- color: white;
3869
- font-weight: bold;
3870
- float: right;
3871
- font-size: 22px;
3872
- line-height: 10px;
3873
- cursor: pointer;
3874
- height: 8px;
3875
- transition: 0.3s;
3876
- }
3877
-
3878
- .closebtn:hover {
3879
- color: black;
3880
- }*/
3881
-
3882
-
3883
- /*.sidenav {
3884
- height: 100%;
3885
- z-index: 1;
3886
- float:left;
3887
- background-color: #111;
3888
- overflow-x: hidden;
3889
- padding-top: 5px;
3890
- }
3891
-
3892
- .sidenav a {
3893
- padding: 6px 6px 6px 32px;
3894
- text-decoration: none;
3895
- font-size: 25px;
3896
- color: #818181;
3897
- display: block;
3898
- }
3899
-
3900
- .sidenav a:hover {
3901
- color: #f1f1f1;
3902
- }
3903
-
3904
- .main {
3905
- margin-left: 200px;
3906
- }*/
3907
-
3908
- /*@media screen and (max-height: 450px) {
3909
- .sidenav {padding-top: 15px;}
3910
- .sidenav a {font-size: 18px;}
3911
- }
3912
- .mo2f_content{
3913
- float:Right;
3914
- width:90%;
3915
- }*/
3916
-
3917
- /* Create two unequal columns that floats next to each other */
3918
- /*.column {
3919
- float: left;
3920
- padding: 10px;
3921
- height: 300px; /* Should be removed. Only for demonstration */
3922
- /*}*/
3923
-
3924
- /*.left {
3925
- width: 13%;
3926
- }
3927
-
3928
- .right {
3929
- width: 87%;
3930
- }*/
3931
-
3932
- /* Clear floats after the columns */
3933
- /*.row:after {
3934
- content: "";
3935
- display: table;
3936
- clear: both;
3937
- }
3938
-
3939
- ----------------
3940
- * {box-sizing: border-box}
3941
- body {font-family: "Lato", sans-serif;}*/
3942
-
3943
- /* Style the tab */
3944
- /*.tab {
3945
- float: left;
3946
- background-color: #23282D;
3947
- width: 15%;
3948
- height: 350px;
3949
- box-shadow: -1px 0px 3px #777777;
3950
- }
3951
-
3952
- /* Style the buttons inside the tab */
3953
- /*.tab button {
3954
- display: block;
3955
- background-color: inherit;
3956
- color: black;
3957
- padding: 18px 16px;
3958
- width: 100%;
3959
- border: none;
3960
- outline: none;
3961
- text-align: left;
3962
- cursor: pointer;
3963
- transition: 0.3s;
3964
- font-size: 17px;
3965
- border: 1px solid Black;
3966
- }
3967
- .tab a {
3968
- display: block;
3969
- background-color: #23282D;
3970
- color: white;
3971
- padding: 18px 16px;
3972
- width: 100%;
3973
-
3974
- outline: none;
3975
- text-align: left;
3976
- cursor: pointer;
3977
- transition: 0.3s;
3978
- font-size: 15px;
3979
- }
3980
- .tab a:hover {
3981
- background-color: #F6821F;
3982
- color: white;
3983
- }
3984
-
3985
- .nav-tab-active, .nav-tab-active:focus, .nav-tab-active:focus:active, .nav-tab-active:hover {
3986
- border-bottom: 1px solid #f1f1f1;
3987
- background: #fff;
3988
- color: #000;
3989
- transform: scale(1,1.03);
3990
- border-bottom: 0px;
3991
- }*/
3992
-
3993
- /* Create an active/current "tab button" class */
3994
- /*.tab a.active {
3995
- background-color: white;
3996
- color:#F6821F;
3997
-
3998
- box-shadow: 0px 0px 5px #aaaaaa;
3999
- font-weight: bold;
4000
- }*/
4001
-
4002
- /* Change background color of buttons on hover */
4003
- /*.tab button:hover {
4004
- background-color: #ddd;
4005
- }*/
4006
-
4007
- /* Create an active/current "tab button" class */
4008
- /*.tab button.active {
4009
- background-color: #ccc;
4010
-
4011
- }
4012
-
4013
- .tooltip {
4014
- position: relative;
4015
- display: inline-block;
4016
- border-bottom: 1px dotted black;
4017
- }
4018
-
4019
- .tooltip .tooltiptext {
4020
- visibility: visible;
4021
- width: 120px;
4022
- background-color: black;
4023
- color: #fff;
4024
- text-align: center;
4025
- border-radius: 6px;
4026
- padding: 5px 0;
4027
- position: absolute;
4028
- z-index: 1;
4029
- bottom: 150%;
4030
- left: 50%;
4031
- margin-left: -60px;
4032
- }
4033
-
4034
- .tooltip .tooltiptext::after {
4035
- content: "";
4036
- position: absolute;
4037
- top: 175%;
4038
- left: 200%;
4039
- margin-left: -5px;
4040
- border-width: 13px;
4041
- border-style: solid;
4042
- border-color: transparent white transparent transparent;
4043
- }
4044
-
4045
- .tooltip:hover .tooltiptext {
4046
-
4047
- visibility: visible;
4048
- }
4049
- .arrow-left {
4050
- visibility: hidden;
4051
- left: 10%;
4052
- width: 0;
4053
- height: 0;
4054
- border-top: 10px solid transparent;
4055
- border-bottom: 10px solid transparent;
4056
- position: relative;
4057
- border-right: 10px solid white;
4058
- }
4059
- .active .arrow-left{
4060
- visibility: visible;
4061
- }*/
4062
- ----------------------------------------------
4063
- /* with network security features.*/
4064
- /*
4065
- .mo2f_backdrop{
4066
- top: 0;
4067
- left: 0;
4068
- position: fixed;
4069
- width: 100% !important;
4070
- background-color: #000 !important;
4071
- opacity: 0.96 !important;
4072
- height: 100% !important;
4073
- z-index: 99999;
4074
- }
4075
-
4076
- .mo2f_fixed_support{
4077
- position:fixed;
4078
- top: 9%;
4079
- left: 81%;
4080
- z-index: 1;
4081
- float:right;
4082
- background-color:#ffba00;
4083
- color:black;
4084
- width:16%;
4085
- font-size: 17px;
4086
- }
4087
-
4088
- .need-help-button {
4089
-
4090
- padding: 4px 8px;
4091
- float:right;
4092
- background-color:#62b772;
4093
- color:#fff;
4094
- width:15%;
4095
- border: 1px solid #018219;
4096
- border-radius: 4px;
4097
- text-shadow: none;
4098
- font-weight: 600;
4099
- font-size: 13px;
4100
- line-height: normal;
4101
- cursor: pointer;
4102
- position:fixed;
4103
- left: 83.5%;
4104
- z-index: 9999;
4105
- height:34px;
4106
- }
4107
-
4108
- .mo2f_orange{
4109
- background:orange;
4110
- }*/
1
+
2
+ .popup_text_not_JQ
3
+ {
4
+ color:black;
5
+ margin-top: 2%;
6
+ margin-left: 5%;
7
+ font-weight: 600;
8
+ font-size: 14px !important;
9
+ }
10
+ .popup_text
11
+ {
12
+ color:black;
13
+ margin-top: 2%;
14
+ font-weight: 600;
15
+ font-size: 14px !important;;
16
+
17
+ }
18
+ .overlay_not_JQ_success{
19
+ width: 450px;
20
+ height: min-content;
21
+ position: fixed;
22
+ float: right;
23
+ z-index: 1;
24
+ top: 0;
25
+ right: 0;
26
+ margin-top: 7%;
27
+ background-color:#bcffb4 !important ;
28
+ /* overflow-x: hidden; */
29
+ transition: 0.5s;
30
+ border-left: 4px solid #46b450;
31
+ }
32
+ .overlay_not_JQ_error {
33
+ width: 450px;
34
+ height: min-content;
35
+ position: fixed;
36
+ float: right;
37
+ z-index: 1;
38
+ top: 0;
39
+ right: 0;
40
+ margin-top: 7%;
41
+ background-color:bisque !important ;
42
+ /* overflow-x: hidden; */
43
+ transition: 0.5s;
44
+ border-left: 4px solid red;
45
+ }
46
+
47
+ .overlay_success {
48
+ width: min-content;
49
+ height: 40px;
50
+ position: fixed;
51
+ float: right;
52
+ z-index: 1;
53
+ top: 0;
54
+ right: 0;
55
+ margin-top: 7%;
56
+ background-color:#bcffb4 !important ;
57
+ /* overflow-x: hidden; */
58
+ border-left: 4px solid #46b450;
59
+ }
60
+ .overlay_error {
61
+ width: min-content;
62
+ height: 40px;
63
+ position: fixed;
64
+ float: right;
65
+ z-index: 1;
66
+ top: 0;
67
+ right: 0;
68
+ margin-top: 7%;
69
+ background-color:bisque !important ;
70
+ /* overflow-x: hidden; */
71
+ border-left: 4px solid red;
72
+ }
73
+
74
+ .link {
75
+ text-decoration: underline;
76
+ color: red;
77
+ cursor: pointer;
78
+ }
79
+
80
  .mo_wpns_help_title {
81
  font-size:17px;
82
  width:100%;
115
  .mo_wpns_tab {
116
  /*overflow: hidden;*/
117
  /*border: 1px solid #ccc;*/
118
+ display: flex;
119
+ flex-wrap: nowrap;
120
+ width: 97%;
121
  background-color: #f1f1f1;
122
+ margin:0px 22px;
123
+ height: 84px;
124
+
125
+ }
126
+ .filebackupmessage{
127
+ text-align: center;
128
+ height: 52px;
129
+ margin-bottom: 2%;
130
+ background-color: rgb(255, 25, 25);
131
+ color: black;
132
+ font-weight: bold;
133
+ padding-top: 1px;
134
  }
135
 
136
  /* Style the buttons inside the tab */
137
  .mo_wpns_tab button {
138
+
139
  background-color: inherit;
140
  float: left;
141
  outline: none;
212
  margin-bottom: 10px;
213
  margin-top: 10px;
214
  height:auto;
215
+ width:71%;
216
  float:left;
217
 
218
 
1446
  background-color: white;
1447
  color:#20b2aa;
1448
  }
1449
+ .ip_lookup_desc,.file_backup_desc{
1450
  background-color:#E6E6E6;
1451
  width:100%;
1452
  margin-top:1%;
1453
  padding:10px;
1454
  }
1455
 
1456
+ .ip_lookup_desc img,.file_backup_desc img{
1457
  margin-left:45%;
1458
  }
1459
 
1894
  line-height: 20px; /* To center it vertically */
1895
  color: white;
1896
  }
1897
+ /*#mo_wpns_bar {
1898
  width: 0%;
1899
  height: 20px;
1900
  background-color: blue;
1901
+ }*/
1902
  .mo_wpns_lightgreen{
1903
  color:rgb(128, 173, 128);
1904
  }
2600
  border: 1px;
2601
  text-align: center;
2602
  text-decoration: none;
2603
+ /*display: inline-table;*/
2604
  font-size: 20px;
2605
  margin: 0px 0px;
2606
  cursor: pointer;
2620
  border: 1px;
2621
  text-align: center;
2622
  text-decoration: none;
2623
+ /*display: inline-table;*/
2624
  font-size: 17px;
2625
  margin: 0px 0px;
2626
  cursor: pointer;
2716
  margin: -4px 2px;
2717
  cursor: pointer;
2718
  }
2719
+ /*Custom login form*/
2720
+ .customloginform{
2721
+ border-collapse: collapse;
2722
+ border:1px solid #20b2aa;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2723
  }
2724
+ .customloginform th {
2725
 
2726
+ font-size: 120%;
 
 
 
2727
  }
2728
+ .customloginform td {
2729
+ width:80%;
2730
+ text-align:left;
2731
+ border:1px solid #20b2aa;
2732
+ padding:1%;
2733
 
 
 
2734
  }
2735
+ .customloginform th{
2736
+ text-align:left;
2737
+ border:1px solid black;
2738
+ padding:1%;
2739
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/images/{normal1.PNG → normal.png} RENAMED
File without changes
includes/images/normal1.png ADDED
Binary file
includes/jquery-qrcode/README.md CHANGED
@@ -1,17 +1,19 @@
1
  # jQuery.qrcode
2
 
3
- [![license][license-img]][github] [![web][web-img]][web] [![github][github-img]][github] [![bower][bower-img]][github]
4
 
5
  jQuery plugin to dynamically generate QR codes. Uses [QR Code Generator][qrcode] (MIT).
 
 
6
 
7
 
8
  ## License
9
  The MIT License (MIT)
10
 
11
- Copyright (c) 2016 Lars Jung (https://larsjung.de)
12
 
13
  Permission is hereby granted, free of charge, to any person obtaining a copy
14
- of this software and agauthciated documentation files (the "Software"), to deal
15
  in the Software without restriction, including without limitation the rights
16
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
  copies of the Software, and to permit persons to whom the Software is
@@ -33,8 +35,8 @@ THE SOFTWARE.
33
  [github]: https://github.com/lrsjng/jquery-qrcode
34
 
35
  [license-img]: https://img.shields.io/badge/license-MIT-a0a060.svg?style=flat-square
36
- [web-img]: https://img.shields.io/badge/web-larsjung.de/qrcode-a0a060.svg?style=flat-square
37
  [github-img]: https://img.shields.io/badge/github-lrsjng/jquery--qrcode-a0a060.svg?style=flat-square
38
- [bower-img]: https://img.shields.io/badge/bower-lrsjng/jquery--qrcode-a0a060.svg?style=flat-square
39
 
40
  [qrcode]: https://github.com/kazuhikoarase/qrcode-generator
 
1
  # jQuery.qrcode
2
 
3
+ [![license][license-img]][github] [![web][web-img]][web] [![github][github-img]][github]
4
 
5
  jQuery plugin to dynamically generate QR codes. Uses [QR Code Generator][qrcode] (MIT).
6
+ There is a jQuery-free lib named [kjua][kjua] that works in all modern browsers
7
+ with crisp codes on all devices.
8
 
9
 
10
  ## License
11
  The MIT License (MIT)
12
 
13
+ Copyright (c) 2019 Lars Jung (https://larsjung.de)
14
 
15
  Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
  in the Software without restriction, including without limitation the rights
18
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
  copies of the Software, and to permit persons to whom the Software is
35
  [github]: https://github.com/lrsjng/jquery-qrcode
36
 
37
  [license-img]: https://img.shields.io/badge/license-MIT-a0a060.svg?style=flat-square
38
+ [web-img]: https://img.shields.io/badge/web-larsjung.de/jquery--qrcode-a0a060.svg?style=flat-square
39
  [github-img]: https://img.shields.io/badge/github-lrsjng/jquery--qrcode-a0a060.svg?style=flat-square
 
40
 
41
  [qrcode]: https://github.com/kazuhikoarase/qrcode-generator
42
+ [kjua]: https://larsjung.de/kjua/
includes/jquery-qrcode/jquery-qrcode.js CHANGED
@@ -1,2332 +1,2815 @@
1
- /*! jquery-qrcode v0.14.0 - https://larsjung.de/jquery-qrcode/ */
2
- (function (vendor_qrcode) {
3
- 'use strict';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- var jq = window.jQuery;
 
 
6
 
7
- // Check if canvas is available in the browser (as Modernizr does)
8
- var hasCanvas = (function () {
9
- var elem = document.createElement('canvas');
10
- return !!(elem.getContext && elem.getContext('2d'));
11
- }());
12
 
13
- // Wrapper for the original QR code generator.
14
- function createQRCode(text, level, version, quiet) {
15
- var qr = {};
16
 
17
- var vqr = vendor_qrcode(version, level);
18
- vqr.addData(text);
19
- vqr.make();
20
 
21
- quiet = quiet || 0;
22
 
23
- var qrModuleCount = vqr.getModuleCount();
24
- var quietModuleCount = vqr.getModuleCount() + 2 * quiet;
25
 
26
- function isDark(row, col) {
27
- row -= quiet;
28
- col -= quiet;
29
 
30
- if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) {
31
- return false;
32
- }
33
- return vqr.isDark(row, col);
 
 
 
34
  }
 
 
 
 
35
 
36
- function addBlank(l, t, r, b) {
37
- var prevIsDark = qr.isDark;
38
- var moduleSize = 1 / quietModuleCount;
39
 
40
- qr.isDark = function (row, col) {
41
- var ml = col * moduleSize;
42
- var mt = row * moduleSize;
43
- var mr = ml + moduleSize;
44
- var mb = mt + moduleSize;
45
 
46
- return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b);
47
- };
 
 
 
 
 
48
  }
 
49
 
50
- qr.text = text;
51
- qr.level = level;
52
- qr.version = version;
53
- qr.moduleCount = quietModuleCount;
54
- qr.isDark = isDark;
55
- qr.addBlank = addBlank;
56
 
57
- return qr;
58
- }
59
 
60
- // Returns a minimal QR code for the given text starting with version `minVersion`.
61
- // Returns `undefined` if `text` is too long to be encoded in `maxVersion`.
62
- function createMinQRCode(text, level, minVersion, maxVersion, quiet) {
63
- minVersion = Math.max(1, minVersion || 1);
64
- maxVersion = Math.min(40, maxVersion || 40);
65
- for (var version = minVersion; version <= maxVersion; version += 1) {
66
- try {
67
- return createQRCode(text, level, version, quiet);
68
- } catch (err) {/* empty */}
69
  }
70
- return undefined;
71
- }
72
 
73
- function drawBackgroundLabel(qr, context, settings) {
74
- var size = settings.size;
75
- var font = 'bold ' + settings.mSize * size + 'px ' + settings.fontname;
76
- var ctx = jq('<canvas/>')[0].getContext('2d');
77
-
78
- ctx.font = font;
79
-
80
- var w = ctx.measureText(settings.label).width;
81
- var sh = settings.mSize;
82
- var sw = w / size;
83
- var sl = (1 - sw) * settings.mPosX;
84
- var st = (1 - sh) * settings.mPosY;
85
- var sr = sl + sw;
86
- var sb = st + sh;
87
- var pad = 0.01;
88
-
89
- if (settings.mode === 1) {
90
- // Strip
91
- qr.addBlank(0, st - pad, size, sb + pad);
92
- } else {
93
- // Box
94
- qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
95
  }
 
 
 
96
 
97
- context.fillStyle = settings.fontcolor;
98
- context.font = font;
99
- context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
100
- }
101
 
102
- function drawBackgroundImage(qr, context, settings) {
103
- var size = settings.size;
104
- var w = settings.image.naturalWidth || 1;
105
- var h = settings.image.naturalHeight || 1;
106
- var sh = settings.mSize;
107
- var sw = sh * w / h;
108
- var sl = (1 - sw) * settings.mPosX;
109
- var st = (1 - sh) * settings.mPosY;
110
- var sr = sl + sw;
111
- var sb = st + sh;
112
- var pad = 0.01;
113
-
114
- if (settings.mode === 3) {
115
- // Strip
116
- qr.addBlank(0, st - pad, size, sb + pad);
117
- } else {
118
- // Box
119
- qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
120
- }
121
 
122
- context.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
123
- }
124
 
125
- function drawBackground(qr, context, settings) {
126
- if (jq(settings.background).is('img')) {
127
- context.drawImage(settings.background, 0, 0, settings.size, settings.size);
128
- } else if (settings.background) {
129
- context.fillStyle = settings.background;
130
- context.fillRect(settings.left, settings.top, settings.size, settings.size);
131
- }
132
 
133
- var mode = settings.mode;
134
- if (mode === 1 || mode === 2) {
135
- drawBackgroundLabel(qr, context, settings);
136
- } else if (mode === 3 || mode === 4) {
137
- drawBackgroundImage(qr, context, settings);
138
- }
139
- }
140
 
141
- function drawModuleDefault(qr, context, settings, left, top, width, row, col) {
142
- if (qr.isDark(row, col)) {
143
- context.rect(left, top, width, width);
144
- }
145
- }
146
 
147
- function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) {
148
- if (nw) {
149
- ctx.moveTo(l + rad, t);
150
- } else {
151
- ctx.moveTo(l, t);
152
- }
153
 
154
- if (ne) {
155
- ctx.lineTo(r - rad, t);
156
- ctx.arcTo(r, t, r, b, rad);
157
- } else {
158
- ctx.lineTo(r, t);
159
- }
160
 
161
- if (se) {
162
- ctx.lineTo(r, b - rad);
163
- ctx.arcTo(r, b, l, b, rad);
164
- } else {
165
- ctx.lineTo(r, b);
 
 
 
166
  }
 
 
 
 
 
 
167
 
168
- if (sw) {
169
- ctx.lineTo(l + rad, b);
170
- ctx.arcTo(l, b, l, t, rad);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  } else {
172
- ctx.lineTo(l, b);
173
  }
 
 
 
 
174
 
175
- if (nw) {
176
- ctx.lineTo(l, t + rad);
177
- ctx.arcTo(l, t, r, t, rad);
 
 
 
178
  } else {
179
- ctx.lineTo(l, t);
180
  }
181
- }
182
 
183
- function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) {
184
- if (nw) {
185
- ctx.moveTo(l + rad, t);
186
- ctx.lineTo(l, t);
187
- ctx.lineTo(l, t + rad);
188
- ctx.arcTo(l, t, l + rad, t, rad);
189
- }
190
 
191
- if (ne) {
192
- ctx.moveTo(r - rad, t);
193
- ctx.lineTo(r, t);
194
- ctx.lineTo(r, t + rad);
195
- ctx.arcTo(r, t, r - rad, t, rad);
196
- }
197
 
198
- if (se) {
199
- ctx.moveTo(r - rad, b);
200
- ctx.lineTo(r, b);
201
- ctx.lineTo(r, b - rad);
202
- ctx.arcTo(r, b, r - rad, b, rad);
203
- }
204
 
205
- if (sw) {
206
- ctx.moveTo(l + rad, b);
207
- ctx.lineTo(l, b);
208
- ctx.lineTo(l, b - rad);
209
- ctx.arcTo(l, b, l + rad, b, rad);
210
- }
211
- }
212
 
213
- function drawModuleRounded(qr, context, settings, left, top, width, row, col) {
214
- var isDark = qr.isDark;
215
- var right = left + width;
216
- var bottom = top + width;
217
- var radius = settings.radius * width;
218
- var rowT = row - 1;
219
- var rowB = row + 1;
220
- var colL = col - 1;
221
- var colR = col + 1;
222
- var center = isDark(row, col);
223
- var northwest = isDark(rowT, colL);
224
- var north = isDark(rowT, col);
225
- var northeast = isDark(rowT, colR);
226
- var east = isDark(row, colR);
227
- var southeast = isDark(rowB, colR);
228
- var south = isDark(rowB, col);
229
- var southwest = isDark(rowB, colL);
230
- var west = isDark(row, colL);
231
-
232
- if (center) {
233
- drawModuleRoundedDark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west);
234
- } else {
235
- drawModuleRoundendLight(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest);
236
- }
237
- }
238
 
239
- function drawModules(qr, context, settings) {
240
- var moduleCount = qr.moduleCount;
241
- var moduleSize = settings.size / moduleCount;
242
- var fn = drawModuleDefault;
243
- var row;
244
- var col;
245
 
246
- if (settings.radius > 0 && settings.radius <= 0.5) {
247
- fn = drawModuleRounded;
248
- }
 
 
249
 
250
- context.beginPath();
251
- for (row = 0; row < moduleCount; row += 1) {
252
- for (col = 0; col < moduleCount; col += 1) {
253
- var l = settings.left + col * moduleSize;
254
- var t = settings.top + row * moduleSize;
255
- var w = moduleSize;
 
 
 
 
 
 
256
 
257
- fn(qr, context, settings, l, t, w, row, col);
 
 
 
258
  }
259
- }
260
- if (jq(settings.fill).is('img')) {
261
- context.strokeStyle = 'rgba(0,0,0,0.5)';
262
- context.lineWidth = 2;
263
- context.stroke();
264
- var prev = context.globalCompositeOperation;
265
- context.globalCompositeOperation = 'destination-out';
266
- context.fill();
267
- context.globalCompositeOperation = prev;
268
-
269
- context.clip();
270
- context.drawImage(settings.fill, 0, 0, settings.size, settings.size);
271
- context.restore();
272
- } else {
273
- context.fillStyle = settings.fill;
274
- context.fill();
275
- }
276
- }
277
 
278
- // Draws QR code to the given `canvas` and returns it.
279
- function drawOnCanvas(canvas, settings) {
280
- var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
281
- if (!qr) {
282
- return null;
283
  }
 
 
284
 
285
- var $canvas = jq(canvas).data('qrcode', qr);
286
- var context = $canvas[0].getContext('2d');
287
 
288
- drawBackground(qr, context, settings);
289
- drawModules(qr, context, settings);
290
 
291
- return $canvas;
292
- }
293
 
294
- // Returns a `canvas` element representing the QR code for the given settings.
295
- function createCanvas(settings) {
296
- var $canvas = jq('<canvas/>').attr('width', settings.size).attr('height', settings.size);
297
- return drawOnCanvas($canvas, settings);
298
- }
299
 
300
- // Returns an `image` element representing the QR code for the given settings.
301
- function createImage(settings) {
302
- return jq('<img/>').attr('src', createCanvas(settings)[0].toDataURL('image/png'));
303
- }
304
 
305
- // Returns a `div` element representing the QR code for the given settings.
306
- function createDiv(settings) {
307
- var qr = createMinQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
308
- if (!qr) {
309
- return null;
310
- }
311
 
312
- // some shortcuts to improve compression
313
- var settings_size = settings.size;
314
- var settings_bgColor = settings.background;
315
- var math_floor = Math.floor;
316
-
317
- var moduleCount = qr.moduleCount;
318
- var moduleSize = math_floor(settings_size / moduleCount);
319
- var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount));
320
-
321
- var row;
322
- var col;
323
-
324
- var containerCSS = {
325
- position: 'relative',
326
- left: 0,
327
- top: 0,
328
- padding: 0,
329
- margin: 0,
330
- width: settings_size,
331
- height: settings_size
332
- };
333
- var darkCSS = {
334
- position: 'absolute',
335
- padding: 0,
336
- margin: 0,
337
- width: moduleSize,
338
- height: moduleSize,
339
- 'background-color': settings.fill
340
- };
341
-
342
- var $div = jq('<div/>').data('qrcode', qr).css(containerCSS);
343
-
344
- if (settings_bgColor) {
345
- $div.css('background-color', settings_bgColor);
346
  }
 
347
 
348
- for (row = 0; row < moduleCount; row += 1) {
349
- for (col = 0; col < moduleCount; col += 1) {
350
- if (qr.isDark(row, col)) {
351
- jq('<div/>')
352
- .css(darkCSS)
353
- .css({
354
- left: offset + col * moduleSize,
355
- top: offset + row * moduleSize
356
- })
357
- .appendTo($div);
358
- }
359
- }
360
  }
 
361
 
362
- return $div;
363
- }
 
 
364
 
365
- function createHTML(settings) {
366
- if (hasCanvas && settings.render === 'canvas') {
367
- return createCanvas(settings);
368
- } else if (hasCanvas && settings.render === 'image') {
369
- return createImage(settings);
 
 
 
 
370
  }
 
371
 
372
- return createDiv(settings);
373
- }
 
 
 
 
 
 
374
 
375
- // Plugin
376
- // ======
377
 
378
- // Default settings
379
- // ----------------
380
- var defaults = {
381
- // render method: `'canvas'`, `'image'` or `'div'`
382
- render: 'canvas',
383
 
384
- // version range somewhere in 1 .. 40
385
- minVersion: 1,
386
- maxVersion: 40,
387
 
388
- // error correction level: `'L'`, `'M'`, `'Q'` or `'H'`
389
- ecLevel: 'L',
390
 
391
- // offset in pixel if drawn onto existing canvas
392
- left: 0,
393
- top: 0,
 
 
 
394
 
395
- // size in pixel
396
- size: 200,
 
 
 
397
 
398
- // code color or image element
399
- fill: '#000',
 
 
 
 
 
400
 
401
- // background color or image element, `null` for transparent background
402
- background: null,
 
 
403
 
404
- // content
405
- text: 'no text',
 
 
406
 
407
- // corner radius relative to module width: 0.0 .. 0.5
408
- radius: 0,
409
 
410
- // quiet zone in modules
411
- quiet: 0,
 
 
412
 
413
- // modes
414
- // 0: normal
415
- // 1: label strip
416
- // 2: label box
417
- // 3: image strip
418
- // 4: image box
419
- mode: 0,
420
 
421
- mSize: 0.1,
422
- mPosX: 0.5,
423
- mPosY: 0.5,
424
 
425
- label: 'no label',
426
- fontname: 'sans',
427
- fontcolor: '#000',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
 
429
- image: null
 
430
  };
431
 
432
- // Register the plugin
433
- // -------------------
434
- jq.fn.qrcode = function (options) {
435
- var settings = jq.extend({}, defaults, options);
 
 
436
 
437
- return this.each(function (idx, el) {
438
- if (el.nodeName.toLowerCase() === 'canvas') {
439
- drawOnCanvas(el, settings);
440
- } else {
441
- jq(el).append(createHTML(settings));
442
- }
443
- });
444
  };
445
- }(function () {
446
- // `qrcode` is the single public function defined by the `QR Code Generator`
447
- //---------------------------------------------------------------------
448
- //
449
- // QR Code Generator for JavaScript
450
- //
451
- // Copyright (c) 2009 Kazuhiko Arase
452
- //
453
- // URL: http://www.d-project.com/
454
- //
455
- // Licensed under the MIT license:
456
- // http://www.opensource.org/licenses/mit-license.php
457
- //
458
- // The word 'QR Code' is registered trademark of
459
- // DENSO WAVE INCORPORATED
460
- // http://www.denso-wave.com/qrcode/faqpatent-e.html
461
- //
462
- //---------------------------------------------------------------------
463
-
464
- var qrcode = function() {
465
-
466
- //---------------------------------------------------------------------
467
- // qrcode
468
- //---------------------------------------------------------------------
469
-
470
- /**
471
- * qrcode
472
- * @param typeNumber 1 to 40
473
- * @param errorCorrectLevel 'L','M','Q','H'
474
- */
475
- var qrcode = function(typeNumber, errorCorrectLevel) {
476
-
477
- var PAD0 = 0xEC;
478
- var PAD1 = 0x11;
479
-
480
- var _typeNumber = typeNumber;
481
- var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel];
482
- var _modules = null;
483
- var _moduleCount = 0;
484
- var _dataCache = null;
485
- var _dataList = new Array();
486
-
487
- var _this = {};
488
-
489
- var makeImpl = function(test, maskPattern) {
490
-
491
- _moduleCount = _typeNumber * 4 + 17;
492
- _modules = function(moduleCount) {
493
- var modules = new Array(moduleCount);
494
- for (var row = 0; row < moduleCount; row += 1) {
495
- modules[row] = new Array(moduleCount);
496
- for (var col = 0; col < moduleCount; col += 1) {
497
- modules[row][col] = null;
498
- }
499
- }
500
- return modules;
501
- }(_moduleCount);
502
-
503
- setupPositionProbePattern(0, 0);
504
- setupPositionProbePattern(_moduleCount - 7, 0);
505
- setupPositionProbePattern(0, _moduleCount - 7);
506
- setupPositionAdjustPattern();
507
- setupTimingPattern();
508
- setupTypeInfo(test, maskPattern);
509
-
510
- if (_typeNumber >= 7) {
511
- setupTypeNumber(test);
512
- }
513
 
514
- if (_dataCache == null) {
515
- _dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList);
 
 
 
 
 
 
 
 
 
 
 
516
  }
517
 
518
- mapData(_dataCache, maskPattern);
519
- };
 
 
520
 
521
- var setupPositionProbePattern = function(row, col) {
 
 
 
522
 
523
- for (var r = -1; r <= 7; r += 1) {
 
524
 
525
- if (row + r <= -1 || _moduleCount <= row + r) continue;
 
526
 
527
- for (var c = -1; c <= 7; c += 1) {
528
 
529
- if (col + c <= -1 || _moduleCount <= col + c) continue;
 
530
 
531
- if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
532
- || (0 <= c && c <= 6 && (r == 0 || r == 6) )
533
- || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
534
- _modules[row + r][col + c] = true;
535
- } else {
536
- _modules[row + r][col + c] = false;
537
- }
538
- }
539
- }
540
- };
541
 
542
- var getBestMaskPattern = function() {
 
 
 
 
 
543
 
544
- var minLostPoint = 0;
545
- var pattern = 0;
546
 
547
- for (var i = 0; i < 8; i += 1) {
548
 
549
- makeImpl(true, i);
 
 
 
 
 
 
 
 
 
 
 
550
 
551
- var lostPoint = QRUtil.getLostPoint(_this);
 
552
 
553
- if (i == 0 || minLostPoint > lostPoint) {
554
- minLostPoint = lostPoint;
555
- pattern = i;
556
- }
557
- }
558
 
559
- return pattern;
560
- };
561
 
562
- var setupTimingPattern = function() {
563
 
564
- for (var r = 8; r < _moduleCount - 8; r += 1) {
565
- if (_modules[r][6] != null) {
566
- continue;
567
- }
568
- _modules[r][6] = (r % 2 == 0);
569
- }
 
 
570
 
571
- for (var c = 8; c < _moduleCount - 8; c += 1) {
572
- if (_modules[6][c] != null) {
573
- continue;
574
- }
575
- _modules[6][c] = (c % 2 == 0);
576
- }
577
- };
578
 
579
- var setupPositionAdjustPattern = function() {
 
580
 
581
- var pos = QRUtil.getPatternPosition(_typeNumber);
 
 
 
 
 
582
 
583
- for (var i = 0; i < pos.length; i += 1) {
 
 
 
 
 
 
 
 
584
 
585
- for (var j = 0; j < pos.length; j += 1) {
 
586
 
587
- var row = pos[i];
588
- var col = pos[j];
589
 
590
- if (_modules[row][col] != null) {
591
- continue;
592
- }
593
 
594
- for (var r = -2; r <= 2; r += 1) {
 
595
 
596
- for (var c = -2; c <= 2; c += 1) {
 
 
597
 
598
- if (r == -2 || r == 2 || c == -2 || c == 2
599
- || (r == 0 && c == 0) ) {
600
- _modules[row + r][col + c] = true;
601
- } else {
602
- _modules[row + r][col + c] = false;
603
- }
604
- }
605
- }
606
- }
607
- }
608
- };
609
 
610
- var setupTypeNumber = function(test) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
611
 
612
- var bits = QRUtil.getBCHTypeNumber(_typeNumber);
 
613
 
614
- for (var i = 0; i < 18; i += 1) {
615
- var mod = (!test && ( (bits >> i) & 1) == 1);
616
- _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
617
- }
618
 
619
- for (var i = 0; i < 18; i += 1) {
620
- var mod = (!test && ( (bits >> i) & 1) == 1);
621
- _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
622
- }
623
- };
624
 
625
- var setupTypeInfo = function(test, maskPattern) {
626
 
627
- var data = (_errorCorrectLevel << 3) | maskPattern;
628
- var bits = QRUtil.getBCHTypeInfo(data);
 
 
 
 
629
 
630
- // vertical
631
- for (var i = 0; i < 15; i += 1) {
 
 
 
 
632
 
633
- var mod = (!test && ( (bits >> i) & 1) == 1);
 
 
 
 
 
634
 
635
- if (i < 6) {
636
- _modules[i][8] = mod;
637
- } else if (i < 8) {
638
- _modules[i + 1][8] = mod;
639
- } else {
640
- _modules[_moduleCount - 15 + i][8] = mod;
641
- }
642
  }
643
 
644
- // horizontal
645
- for (var i = 0; i < 15; i += 1) {
 
 
 
 
646
 
647
- var mod = (!test && ( (bits >> i) & 1) == 1);
 
 
648
 
649
- if (i < 8) {
650
- _modules[8][_moduleCount - i - 1] = mod;
651
- } else if (i < 9) {
652
- _modules[8][15 - i - 1 + 1] = mod;
653
- } else {
654
- _modules[8][15 - i - 1] = mod;
655
- }
656
- }
657
 
658
- // fixed module
659
- _modules[_moduleCount - 8][8] = (!test);
660
- };
661
 
662
- var mapData = function(data, maskPattern) {
 
663
 
664
- var inc = -1;
665
- var row = _moduleCount - 1;
666
- var bitIndex = 7;
667
- var byteIndex = 0;
668
- var maskFunc = QRUtil.getMaskFunction(maskPattern);
669
 
670
- for (var col = _moduleCount - 1; col > 0; col -= 2) {
 
 
671
 
672
- if (col == 6) col -= 1;
 
673
 
674
- while (true) {
 
 
675
 
676
- for (var c = 0; c < 2; c += 1) {
677
 
678
- if (_modules[row][col - c] == null) {
 
679
 
680
- var dark = false;
 
 
 
 
 
 
681
 
682
- if (byteIndex < data.length) {
683
- dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
684
- }
685
 
686
- var mask = maskFunc(row, col - c);
 
 
687
 
688
- if (mask) {
689
- dark = !dark;
690
- }
 
691
 
692
- _modules[row][col - c] = dark;
693
- bitIndex -= 1;
694
 
695
- if (bitIndex == -1) {
696
- byteIndex += 1;
697
- bitIndex = 7;
698
- }
699
- }
700
- }
 
 
 
 
701
 
702
- row += inc;
 
703
 
704
- if (row < 0 || _moduleCount <= row) {
705
- row -= inc;
706
- inc = -inc;
707
- break;
708
- }
709
- }
710
- }
711
- };
712
 
713
- var createBytes = function(buffer, rsBlocks) {
 
 
 
 
 
 
 
 
 
714
 
715
- var offset = 0;
716
 
717
- var maxDcCount = 0;
718
- var maxEcCount = 0;
 
719
 
720
- var dcdata = new Array(rsBlocks.length);
721
- var ecdata = new Array(rsBlocks.length);
 
 
 
 
722
 
723
- for (var r = 0; r < rsBlocks.length; r += 1) {
724
 
725
- var dcCount = rsBlocks[r].dataCount;
726
- var ecCount = rsBlocks[r].totalCount - dcCount;
727
 
728
- maxDcCount = Math.max(maxDcCount, dcCount);
729
- maxEcCount = Math.max(maxEcCount, ecCount);
 
 
 
 
730
 
731
- dcdata[r] = new Array(dcCount);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
732
 
733
- for (var i = 0; i < dcdata[r].length; i += 1) {
734
- dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
735
- }
736
- offset += dcCount;
737
 
738
- var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
739
- var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
740
 
741
- var modPoly = rawPoly.mod(rsPoly);
742
- ecdata[r] = new Array(rsPoly.getLength() - 1);
743
- for (var i = 0; i < ecdata[r].length; i += 1) {
744
- var modIndex = i + modPoly.getLength() - ecdata[r].length;
745
- ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;
 
 
 
 
 
 
 
 
 
 
 
746
  }
 
 
747
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
 
749
- var totalCodeCount = 0;
750
- for (var i = 0; i < rsBlocks.length; i += 1) {
751
- totalCodeCount += rsBlocks[i].totalCount;
752
- }
 
 
 
753
 
754
- var data = new Array(totalCodeCount);
755
- var index = 0;
 
 
 
 
 
756
 
757
- for (var i = 0; i < maxDcCount; i += 1) {
758
- for (var r = 0; r < rsBlocks.length; r += 1) {
759
- if (i < dcdata[r].length) {
760
- data[index] = dcdata[r][i];
761
- index += 1;
762
- }
763
- }
764
- }
765
 
766
- for (var i = 0; i < maxEcCount; i += 1) {
767
- for (var r = 0; r < rsBlocks.length; r += 1) {
768
- if (i < ecdata[r].length) {
769
- data[index] = ecdata[r][i];
770
- index += 1;
771
- }
772
- }
773
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
 
775
- return data;
776
- };
 
 
 
 
 
777
 
778
- var createData = function(typeNumber, errorCorrectLevel, dataList) {
779
 
780
- var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
781
 
782
- var buffer = qrBitBuffer();
783
 
784
- for (var i = 0; i < dataList.length; i += 1) {
785
- var data = dataList[i];
786
- buffer.put(data.getMode(), 4);
787
- buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
788
- data.write(buffer);
789
- }
 
 
790
 
791
- // calc num max data.
792
- var totalDataCount = 0;
793
- for (var i = 0; i < rsBlocks.length; i += 1) {
794
- totalDataCount += rsBlocks[i].dataCount;
795
- }
796
 
797
- if (buffer.getLengthInBits() > totalDataCount * 8) {
798
- throw new Error('code length overflow. ('
799
- + buffer.getLengthInBits()
800
- + '>'
801
- + totalDataCount * 8
802
- + ')');
803
- }
804
 
805
- // end code
806
- if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
807
- buffer.put(0, 4);
808
- }
 
 
 
 
809
 
810
- // padding
811
- while (buffer.getLengthInBits() % 8 != 0) {
812
- buffer.putBit(false);
813
- }
814
 
815
- // padding
816
- while (true) {
817
 
818
- if (buffer.getLengthInBits() >= totalDataCount * 8) {
819
- break;
820
- }
821
- buffer.put(PAD0, 8);
 
 
 
 
822
 
823
- if (buffer.getLengthInBits() >= totalDataCount * 8) {
824
- break;
825
- }
826
- buffer.put(PAD1, 8);
827
- }
828
 
829
- return createBytes(buffer, rsBlocks);
830
- };
831
 
832
- _this.addData = function(data) {
833
- var newData = qr8BitByte(data);
834
- _dataList.push(newData);
835
- _dataCache = null;
836
- };
837
 
838
- _this.isDark = function(row, col) {
839
- if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
840
- throw new Error(row + ',' + col);
841
- }
842
- return _modules[row][col];
843
- };
844
 
845
- _this.getModuleCount = function() {
846
- return _moduleCount;
847
- };
848
 
849
- _this.make = function() {
850
- makeImpl(false, getBestMaskPattern() );
851
- };
852
 
853
- _this.createTableTag = function(cellSize, margin) {
 
854
 
855
- cellSize = cellSize || 2;
856
- margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
857
 
858
- var qrHtml = '';
 
 
859
 
860
- qrHtml += '<table style="';
861
- qrHtml += ' border-width: 0px; border-style: none;';
862
- qrHtml += ' border-collapse: collapse;';
863
- qrHtml += ' padding: 0px; margin: ' + margin + 'px;';
864
- qrHtml += '">';
865
- qrHtml += '<tbody>';
866
-
867
- for (var r = 0; r < _this.getModuleCount(); r += 1) {
868
-
869
- qrHtml += '<tr>';
870
-
871
- for (var c = 0; c < _this.getModuleCount(); c += 1) {
872
- qrHtml += '<td style="';
873
- qrHtml += ' border-width: 0px; border-style: none;';
874
- qrHtml += ' border-collapse: collapse;';
875
- qrHtml += ' padding: 0px; margin: 0px;';
876
- qrHtml += ' width: ' + cellSize + 'px;';
877
- qrHtml += ' height: ' + cellSize + 'px;';
878
- qrHtml += ' background-color: ';
879
- qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';
880
- qrHtml += ';';
881
- qrHtml += '"/>';
882
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
883
 
884
- qrHtml += '</tr>';
 
 
 
 
 
 
 
 
 
 
 
885
  }
 
 
886
 
887
- qrHtml += '</tbody>';
888
- qrHtml += '</table>';
 
 
 
 
 
 
 
 
 
 
 
889
 
890
- return qrHtml;
891
- };
892
 
893
- _this.createImgTag = function(cellSize, margin) {
894
 
895
- cellSize = cellSize || 2;
896
- margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
 
 
 
 
 
897
 
898
- var size = _this.getModuleCount() * cellSize + margin * 2;
899
- var min = margin;
900
- var max = size - margin;
901
 
902
- return createImgTag(size, size, function(x, y) {
903
- if (min <= x && x < max && min <= y && y < max) {
904
- var c = Math.floor( (x - min) / cellSize);
905
- var r = Math.floor( (y - min) / cellSize);
906
- return _this.isDark(r, c)? 0 : 1;
907
- } else {
908
- return 1;
909
- }
910
- } );
911
- };
912
 
913
- return _this;
914
- };
915
 
916
- //---------------------------------------------------------------------
917
- // qrcode.stringToBytes
918
- //---------------------------------------------------------------------
919
 
920
- qrcode.stringToBytes = function(s) {
921
- var bytes = new Array();
922
- for (var i = 0; i < s.length; i += 1) {
923
- var c = s.charCodeAt(i);
924
- bytes.push(c & 0xff);
925
- }
926
- return bytes;
927
- };
928
 
929
- //---------------------------------------------------------------------
930
- // qrcode.createStringToBytes
931
- //---------------------------------------------------------------------
932
 
933
- /**
934
- * @param unicodeData base64 string of byte array.
935
- * [16bit Unicode],[16bit Bytes], ...
936
- * @param numChars
937
- */
938
- qrcode.createStringToBytes = function(unicodeData, numChars) {
 
 
 
 
 
 
 
939
 
940
- // create conversion map.
941
 
942
- var unicodeMap = function() {
943
 
944
- var bin = base64DecodeInputStream(unicodeData);
945
- var read = function() {
946
- var b = bin.read();
947
- if (b == -1) throw new Error();
948
- return b;
949
- };
950
 
951
- var count = 0;
952
- var unicodeMap = {};
953
- while (true) {
954
- var b0 = bin.read();
955
- if (b0 == -1) break;
956
- var b1 = read();
957
- var b2 = read();
958
- var b3 = read();
959
- var k = String.fromCharCode( (b0 << 8) | b1);
960
- var v = (b2 << 8) | b3;
961
- unicodeMap[k] = v;
962
- count += 1;
963
- }
964
- if (count != numChars) {
965
- throw new Error(count + ' != ' + numChars);
966
- }
967
 
968
- return unicodeMap;
969
- }();
970
 
971
- var unknownChar = '?'.charCodeAt(0);
 
 
972
 
973
- return function(s) {
974
- var bytes = new Array();
975
- for (var i = 0; i < s.length; i += 1) {
976
- var c = s.charCodeAt(i);
977
- if (c < 128) {
978
- bytes.push(c);
979
- } else {
980
- var b = unicodeMap[s.charAt(i)];
981
- if (typeof b == 'number') {
982
- if ( (b & 0xff) == b) {
983
- // 1byte
984
- bytes.push(b);
985
- } else {
986
- // 2bytes
987
- bytes.push(b >>> 8);
988
- bytes.push(b & 0xff);
989
- }
990
- } else {
991
- bytes.push(unknownChar);
992
- }
993
- }
994
- }
995
- return bytes;
996
- };
997
- };
998
 
999
- //---------------------------------------------------------------------
1000
- // QRMode
1001
- //---------------------------------------------------------------------
1002
 
1003
- var QRMode = {
1004
- MODE_NUMBER : 1 << 0,
1005
- MODE_ALPHA_NUM : 1 << 1,
1006
- MODE_8BIT_BYTE : 1 << 2,
1007
- MODE_KANJI : 1 << 3
1008
- };
1009
 
1010
- //---------------------------------------------------------------------
1011
- // QRErrorCorrectLevel
1012
- //---------------------------------------------------------------------
1013
 
1014
- var QRErrorCorrectLevel = {
1015
- L : 1,
1016
- M : 0,
1017
- Q : 3,
1018
- H : 2
1019
- };
1020
 
1021
- //---------------------------------------------------------------------
1022
- // QRMaskPattern
1023
- //---------------------------------------------------------------------
1024
-
1025
- var QRMaskPattern = {
1026
- PATTERN000 : 0,
1027
- PATTERN001 : 1,
1028
- PATTERN010 : 2,
1029
- PATTERN011 : 3,
1030
- PATTERN100 : 4,
1031
- PATTERN101 : 5,
1032
- PATTERN110 : 6,
1033
- PATTERN111 : 7
1034
- };
1035
 
1036
- //---------------------------------------------------------------------
1037
- // QRUtil
1038
- //---------------------------------------------------------------------
1039
-
1040
- var QRUtil = function() {
1041
-
1042
- var PATTERN_POSITION_TABLE = [
1043
- [],
1044
- [6, 18],
1045
- [6, 22],
1046
- [6, 26],
1047
- [6, 30],
1048
- [6, 34],
1049
- [6, 22, 38],
1050
- [6, 24, 42],
1051
- [6, 26, 46],
1052
- [6, 28, 50],
1053
- [6, 30, 54],
1054
- [6, 32, 58],
1055
- [6, 34, 62],
1056
- [6, 26, 46, 66],
1057
- [6, 26, 48, 70],
1058
- [6, 26, 50, 74],
1059
- [6, 30, 54, 78],
1060
- [6, 30, 56, 82],
1061
- [6, 30, 58, 86],
1062
- [6, 34, 62, 90],
1063
- [6, 28, 50, 72, 94],
1064
- [6, 26, 50, 74, 98],
1065
- [6, 30, 54, 78, 102],
1066
- [6, 28, 54, 80, 106],
1067
- [6, 32, 58, 84, 110],
1068
- [6, 30, 58, 86, 114],
1069
- [6, 34, 62, 90, 118],
1070
- [6, 26, 50, 74, 98, 122],
1071
- [6, 30, 54, 78, 102, 126],
1072
- [6, 26, 52, 78, 104, 130],
1073
- [6, 30, 56, 82, 108, 134],
1074
- [6, 34, 60, 86, 112, 138],
1075
- [6, 30, 58, 86, 114, 142],
1076
- [6, 34, 62, 90, 118, 146],
1077
- [6, 30, 54, 78, 102, 126, 150],
1078
- [6, 24, 50, 76, 102, 128, 154],
1079
- [6, 28, 54, 80, 106, 132, 158],
1080
- [6, 32, 58, 84, 110, 136, 162],
1081
- [6, 26, 54, 82, 110, 138, 166],
1082
- [6, 30, 58, 86, 114, 142, 170]
1083
- ];
1084
- var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
1085
- var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
1086
- var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
1087
-
1088
- var _this = {};
1089
-
1090
- var getBCHDigit = function(data) {
1091
- var digit = 0;
1092
- while (data != 0) {
1093
- digit += 1;
1094
- data >>>= 1;
1095
- }
1096
- return digit;
1097
- };
1098
 
1099
- _this.getBCHTypeInfo = function(data) {
1100
- var d = data << 10;
1101
- while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {
1102
- d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );
1103
- }
1104
- return ( (data << 10) | d) ^ G15_MASK;
1105
- };
1106
 
1107
- _this.getBCHTypeNumber = function(data) {
1108
- var d = data << 12;
1109
- while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {
1110
- d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );
1111
- }
1112
- return (data << 12) | d;
1113
- };
1114
-
1115
- _this.getPatternPosition = function(typeNumber) {
1116
- return PATTERN_POSITION_TABLE[typeNumber - 1];
1117
- };
1118
-
1119
- _this.getMaskFunction = function(maskPattern) {
1120
-
1121
- switch (maskPattern) {
1122
-
1123
- case QRMaskPattern.PATTERN000 :
1124
- return function(i, j) { return (i + j) % 2 == 0; };
1125
- case QRMaskPattern.PATTERN001 :
1126
- return function(i, j) { return i % 2 == 0; };
1127
- case QRMaskPattern.PATTERN010 :
1128
- return function(i, j) { return j % 3 == 0; };
1129
- case QRMaskPattern.PATTERN011 :
1130
- return function(i, j) { return (i + j) % 3 == 0; };
1131
- case QRMaskPattern.PATTERN100 :
1132
- return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };
1133
- case QRMaskPattern.PATTERN101 :
1134
- return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };
1135
- case QRMaskPattern.PATTERN110 :
1136
- return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };
1137
- case QRMaskPattern.PATTERN111 :
1138
- return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };
1139
-
1140
- default :
1141
- throw new Error('bad maskPattern:' + maskPattern);
1142
- }
1143
- };
1144
 
1145
- _this.getErrorCorrectPolynomial = function(errorCorrectLength) {
1146
- var a = qrPolynomial([1], 0);
1147
- for (var i = 0; i < errorCorrectLength; i += 1) {
1148
- a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );
1149
- }
1150
- return a;
1151
- };
1152
 
1153
- _this.getLengthInBits = function(mode, type) {
1154
 
1155
- if (1 <= type && type < 10) {
1156
 
1157
- // 1 - 9
 
 
 
 
1158
 
1159
- switch(mode) {
1160
- case QRMode.MODE_NUMBER : return 10;
1161
- case QRMode.MODE_ALPHA_NUM : return 9;
1162
- case QRMode.MODE_8BIT_BYTE : return 8;
1163
- case QRMode.MODE_KANJI : return 8;
1164
- default :
1165
- throw new Error('mode:' + mode);
1166
- }
1167
 
1168
- } else if (type < 27) {
1169
 
1170
- // 10 - 26
 
 
1171
 
1172
- switch(mode) {
1173
- case QRMode.MODE_NUMBER : return 12;
1174
- case QRMode.MODE_ALPHA_NUM : return 11;
1175
- case QRMode.MODE_8BIT_BYTE : return 16;
1176
- case QRMode.MODE_KANJI : return 10;
1177
- default :
1178
- throw new Error('mode:' + mode);
1179
- }
1180
 
1181
- } else if (type < 41) {
 
 
 
1182
 
1183
- // 27 - 40
 
 
1184
 
1185
- switch(mode) {
1186
- case QRMode.MODE_NUMBER : return 14;
1187
- case QRMode.MODE_ALPHA_NUM : return 13;
1188
- case QRMode.MODE_8BIT_BYTE : return 16;
1189
- case QRMode.MODE_KANJI : return 12;
1190
- default :
1191
- throw new Error('mode:' + mode);
1192
- }
1193
 
1194
- } else {
1195
- throw new Error('type:' + type);
1196
- }
1197
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1198
 
1199
- _this.getLostPoint = function(qrcode) {
1200
 
1201
- var moduleCount = qrcode.getModuleCount();
1202
 
1203
- var lostPoint = 0;
 
 
 
 
 
 
 
 
 
 
 
 
1204
 
1205
- // LEVEL1
1206
 
1207
- for (var row = 0; row < moduleCount; row += 1) {
1208
- for (var col = 0; col < moduleCount; col += 1) {
1209
 
1210
- var sameCount = 0;
1211
- var dark = qrcode.isDark(row, col);
 
 
1212
 
1213
- for (var r = -1; r <= 1; r += 1) {
1214
 
1215
- if (row + r < 0 || moduleCount <= row + r) {
1216
- continue;
1217
- }
1218
 
1219
- for (var c = -1; c <= 1; c += 1) {
1220
 
1221
- if (col + c < 0 || moduleCount <= col + c) {
1222
- continue;
1223
- }
1224
 
1225
- if (r == 0 && c == 0) {
1226
- continue;
1227
- }
 
1228
 
1229
- if (dark == qrcode.isDark(row + r, col + c) ) {
1230
- sameCount += 1;
1231
- }
1232
- }
1233
- }
1234
 
1235
- if (sameCount > 5) {
1236
- lostPoint += (3 + sameCount - 5);
1237
- }
1238
- }
1239
- };
1240
-
1241
- // LEVEL2
1242
-
1243
- for (var row = 0; row < moduleCount - 1; row += 1) {
1244
- for (var col = 0; col < moduleCount - 1; col += 1) {
1245
- var count = 0;
1246
- if (qrcode.isDark(row, col) ) count += 1;
1247
- if (qrcode.isDark(row + 1, col) ) count += 1;
1248
- if (qrcode.isDark(row, col + 1) ) count += 1;
1249
- if (qrcode.isDark(row + 1, col + 1) ) count += 1;
1250
- if (count == 0 || count == 4) {
1251
- lostPoint += 3;
1252
- }
1253
- }
1254
- }
1255
 
1256
- // LEVEL3
1257
-
1258
- for (var row = 0; row < moduleCount; row += 1) {
1259
- for (var col = 0; col < moduleCount - 6; col += 1) {
1260
- if (qrcode.isDark(row, col)
1261
- && !qrcode.isDark(row, col + 1)
1262
- && qrcode.isDark(row, col + 2)
1263
- && qrcode.isDark(row, col + 3)
1264
- && qrcode.isDark(row, col + 4)
1265
- && !qrcode.isDark(row, col + 5)
1266
- && qrcode.isDark(row, col + 6) ) {
1267
- lostPoint += 40;
1268
- }
1269
- }
1270
- }
1271
 
1272
- for (var col = 0; col < moduleCount; col += 1) {
1273
- for (var row = 0; row < moduleCount - 6; row += 1) {
1274
- if (qrcode.isDark(row, col)
1275
- && !qrcode.isDark(row + 1, col)
1276
- && qrcode.isDark(row + 2, col)
1277
- && qrcode.isDark(row + 3, col)
1278
- && qrcode.isDark(row + 4, col)
1279
- && !qrcode.isDark(row + 5, col)
1280
- && qrcode.isDark(row + 6, col) ) {
1281
- lostPoint += 40;
1282
- }
1283
- }
1284
- }
1285
 
1286
- // LEVEL4
 
1287
 
1288
- var darkCount = 0;
1289
 
1290
- for (var col = 0; col < moduleCount; col += 1) {
1291
- for (var row = 0; row < moduleCount; row += 1) {
1292
- if (qrcode.isDark(row, col) ) {
1293
- darkCount += 1;
1294
- }
1295
- }
1296
- }
1297
 
1298
- var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
1299
- lostPoint += ratio * 10;
 
 
1300
 
1301
- return lostPoint;
1302
- };
 
 
 
1303
 
1304
- return _this;
1305
- }();
 
1306
 
1307
- //---------------------------------------------------------------------
1308
- // QRMath
1309
- //---------------------------------------------------------------------
1310
 
1311
- var QRMath = function() {
 
 
 
1312
 
1313
- var EXP_TABLE = new Array(256);
1314
- var LOG_TABLE = new Array(256);
 
1315
 
1316
- // initialize tables
1317
- for (var i = 0; i < 8; i += 1) {
1318
- EXP_TABLE[i] = 1 << i;
1319
- }
1320
- for (var i = 8; i < 256; i += 1) {
1321
- EXP_TABLE[i] = EXP_TABLE[i - 4]
1322
- ^ EXP_TABLE[i - 5]
1323
- ^ EXP_TABLE[i - 6]
1324
- ^ EXP_TABLE[i - 8];
1325
- }
1326
- for (var i = 0; i < 255; i += 1) {
1327
- LOG_TABLE[EXP_TABLE[i] ] = i;
1328
- }
1329
 
1330
- var _this = {};
 
1331
 
1332
- _this.glog = function(n) {
 
 
1333
 
1334
- if (n < 1) {
1335
- throw new Error('glog(' + n + ')');
1336
- }
1337
 
1338
- return LOG_TABLE[n];
1339
- };
1340
 
1341
- _this.gexp = function(n) {
1342
 
1343
- while (n < 0) {
1344
- n += 255;
1345
- }
1346
 
1347
- while (n >= 256) {
1348
- n -= 255;
1349
- }
1350
 
1351
- return EXP_TABLE[n];
1352
- };
1353
 
1354
- return _this;
1355
- }();
1356
 
1357
- //---------------------------------------------------------------------
1358
- // qrPolynomial
1359
- //---------------------------------------------------------------------
1360
 
1361
- function qrPolynomial(num, shift) {
 
 
 
1362
 
1363
- if (typeof num.length == 'undefined') {
1364
- throw new Error(num.length + '/' + shift);
 
 
 
1365
  }
 
 
1366
 
1367
- var _num = function() {
1368
- var offset = 0;
1369
- while (offset < num.length && num[offset] == 0) {
1370
- offset += 1;
1371
- }
1372
- var _num = new Array(num.length - offset + shift);
1373
- for (var i = 0; i < num.length - offset; i += 1) {
1374
- _num[i] = num[i + offset];
1375
- }
1376
- return _num;
1377
- }();
1378
-
1379
- var _this = {};
1380
 
1381
- _this.getAt = function(index) {
1382
- return _num[index];
1383
- };
 
 
 
1384
 
1385
- _this.getLength = function() {
1386
- return _num.length;
1387
- };
1388
 
1389
- _this.multiply = function(e) {
 
 
1390
 
1391
- var num = new Array(_this.getLength() + e.getLength() - 1);
1392
 
1393
- for (var i = 0; i < _this.getLength(); i += 1) {
1394
- for (var j = 0; j < e.getLength(); j += 1) {
1395
- num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );
1396
- }
1397
- }
1398
 
1399
- return qrPolynomial(num, 0);
1400
- };
1401
 
1402
- _this.mod = function(e) {
 
 
1403
 
1404
- if (_this.getLength() - e.getLength() < 0) {
1405
- return _this;
1406
- }
1407
 
1408
- var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );
1409
 
1410
- var num = new Array(_this.getLength() );
1411
- for (var i = 0; i < _this.getLength(); i += 1) {
1412
- num[i] = _this.getAt(i);
1413
- }
1414
 
1415
- for (var i = 0; i < e.getLength(); i += 1) {
1416
- num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);
1417
- }
1418
 
1419
- // recursive call
1420
- return qrPolynomial(num, 0).mod(e);
1421
- };
 
 
 
1422
 
1423
- return _this;
1424
- };
 
 
1425
 
1426
- //---------------------------------------------------------------------
1427
- // QRRSBlock
1428
- //---------------------------------------------------------------------
1429
-
1430
- var QRRSBlock = function() {
1431
-
1432
- var RS_BLOCK_TABLE = [
1433
-
1434
- // L
1435
- // M
1436
- // Q
1437
- // H
1438
-
1439
- // 1
1440
- [1, 26, 19],
1441
- [1, 26, 16],
1442
- [1, 26, 13],
1443
- [1, 26, 9],
1444
-
1445
- // 2
1446
- [1, 44, 34],
1447
- [1, 44, 28],
1448
- [1, 44, 22],
1449
- [1, 44, 16],
1450
-
1451
- // 3
1452
- [1, 70, 55],
1453
- [1, 70, 44],
1454
- [2, 35, 17],
1455
- [2, 35, 13],
1456
-
1457
- // 4
1458
- [1, 100, 80],
1459
- [2, 50, 32],
1460
- [2, 50, 24],
1461
- [4, 25, 9],
1462
-
1463
- // 5
1464
- [1, 134, 108],
1465
- [2, 67, 43],
1466
- [2, 33, 15, 2, 34, 16],
1467
- [2, 33, 11, 2, 34, 12],
1468
-
1469
- // 6
1470
- [2, 86, 68],
1471
- [4, 43, 27],
1472
- [4, 43, 19],
1473
- [4, 43, 15],
1474
-
1475
- // 7
1476
- [2, 98, 78],
1477
- [4, 49, 31],
1478
- [2, 32, 14, 4, 33, 15],
1479
- [4, 39, 13, 1, 40, 14],
1480
-
1481
- // 8
1482
- [2, 121, 97],
1483
- [2, 60, 38, 2, 61, 39],
1484
- [4, 40, 18, 2, 41, 19],
1485
- [4, 40, 14, 2, 41, 15],
1486
-
1487
- // 9
1488
- [2, 146, 116],
1489
- [3, 58, 36, 2, 59, 37],
1490
- [4, 36, 16, 4, 37, 17],
1491
- [4, 36, 12, 4, 37, 13],
1492
-
1493
- // 10
1494
- [2, 86, 68, 2, 87, 69],
1495
- [4, 69, 43, 1, 70, 44],
1496
- [6, 43, 19, 2, 44, 20],
1497
- [6, 43, 15, 2, 44, 16],
1498
-
1499
- // 11
1500
- [4, 101, 81],
1501
- [1, 80, 50, 4, 81, 51],
1502
- [4, 50, 22, 4, 51, 23],
1503
- [3, 36, 12, 8, 37, 13],
1504
-
1505
- // 12
1506
- [2, 116, 92, 2, 117, 93],
1507
- [6, 58, 36, 2, 59, 37],
1508
- [4, 46, 20, 6, 47, 21],
1509
- [7, 42, 14, 4, 43, 15],
1510
-
1511
- // 13
1512
- [4, 133, 107],
1513
- [8, 59, 37, 1, 60, 38],
1514
- [8, 44, 20, 4, 45, 21],
1515
- [12, 33, 11, 4, 34, 12],
1516
-
1517
- // 14
1518
- [3, 145, 115, 1, 146, 116],
1519
- [4, 64, 40, 5, 65, 41],
1520
- [11, 36, 16, 5, 37, 17],
1521
- [11, 36, 12, 5, 37, 13],
1522
-
1523
- // 15
1524
- [5, 109, 87, 1, 110, 88],
1525
- [5, 65, 41, 5, 66, 42],
1526
- [5, 54, 24, 7, 55, 25],
1527
- [11, 36, 12, 7, 37, 13],
1528
-
1529
- // 16
1530
- [5, 122, 98, 1, 123, 99],
1531
- [7, 73, 45, 3, 74, 46],
1532
- [15, 43, 19, 2, 44, 20],
1533
- [3, 45, 15, 13, 46, 16],
1534
-
1535
- // 17
1536
- [1, 135, 107, 5, 136, 108],
1537
- [10, 74, 46, 1, 75, 47],
1538
- [1, 50, 22, 15, 51, 23],
1539
- [2, 42, 14, 17, 43, 15],
1540
-
1541
- // 18
1542
- [5, 150, 120, 1, 151, 121],
1543
- [9, 69, 43, 4, 70, 44],
1544
- [17, 50, 22, 1, 51, 23],
1545
- [2, 42, 14, 19, 43, 15],
1546
-
1547
- // 19
1548
- [3, 141, 113, 4, 142, 114],
1549
- [3, 70, 44, 11, 71, 45],
1550
- [17, 47, 21, 4, 48, 22],
1551
- [9, 39, 13, 16, 40, 14],
1552
-
1553
- // 20
1554
- [3, 135, 107, 5, 136, 108],
1555
- [3, 67, 41, 13, 68, 42],
1556
- [15, 54, 24, 5, 55, 25],
1557
- [15, 43, 15, 10, 44, 16],
1558
-
1559
- // 21
1560
- [4, 144, 116, 4, 145, 117],
1561
- [17, 68, 42],
1562
- [17, 50, 22, 6, 51, 23],
1563
- [19, 46, 16, 6, 47, 17],
1564
-
1565
- // 22
1566
- [2, 139, 111, 7, 140, 112],
1567
- [17, 74, 46],
1568
- [7, 54, 24, 16, 55, 25],
1569
- [34, 37, 13],
1570
-
1571
- // 23
1572
- [4, 151, 121, 5, 152, 122],
1573
- [4, 75, 47, 14, 76, 48],
1574
- [11, 54, 24, 14, 55, 25],
1575
- [16, 45, 15, 14, 46, 16],
1576
-
1577
- // 24
1578
- [6, 147, 117, 4, 148, 118],
1579
- [6, 73, 45, 14, 74, 46],
1580
- [11, 54, 24, 16, 55, 25],
1581
- [30, 46, 16, 2, 47, 17],
1582
-
1583
- // 25
1584
- [8, 132, 106, 4, 133, 107],
1585
- [8, 75, 47, 13, 76, 48],
1586
- [7, 54, 24, 22, 55, 25],
1587
- [22, 45, 15, 13, 46, 16],
1588
-
1589
- // 26
1590
- [10, 142, 114, 2, 143, 115],
1591
- [19, 74, 46, 4, 75, 47],
1592
- [28, 50, 22, 6, 51, 23],
1593
- [33, 46, 16, 4, 47, 17],
1594
-
1595
- // 27
1596
- [8, 152, 122, 4, 153, 123],
1597
- [22, 73, 45, 3, 74, 46],
1598
- [8, 53, 23, 26, 54, 24],
1599
- [12, 45, 15, 28, 46, 16],
1600
-
1601
- // 28
1602
- [3, 147, 117, 10, 148, 118],
1603
- [3, 73, 45, 23, 74, 46],
1604
- [4, 54, 24, 31, 55, 25],
1605
- [11, 45, 15, 31, 46, 16],
1606
-
1607
- // 29
1608
- [7, 146, 116, 7, 147, 117],
1609
- [21, 73, 45, 7, 74, 46],
1610
- [1, 53, 23, 37, 54, 24],
1611
- [19, 45, 15, 26, 46, 16],
1612
-
1613
- // 30
1614
- [5, 145, 115, 10, 146, 116],
1615
- [19, 75, 47, 10, 76, 48],
1616
- [15, 54, 24, 25, 55, 25],
1617
- [23, 45, 15, 25, 46, 16],
1618
-
1619
- // 31
1620
- [13, 145, 115, 3, 146, 116],
1621
- [2, 74, 46, 29, 75, 47],
1622
- [42, 54, 24, 1, 55, 25],
1623
- [23, 45, 15, 28, 46, 16],
1624
-
1625
- // 32
1626
- [17, 145, 115],
1627
- [10, 74, 46, 23, 75, 47],
1628
- [10, 54, 24, 35, 55, 25],
1629
- [19, 45, 15, 35, 46, 16],
1630
-
1631
- // 33
1632
- [17, 145, 115, 1, 146, 116],
1633
- [14, 74, 46, 21, 75, 47],
1634
- [29, 54, 24, 19, 55, 25],
1635
- [11, 45, 15, 46, 46, 16],
1636
-
1637
- // 34
1638
- [13, 145, 115, 6, 146, 116],
1639
- [14, 74, 46, 23, 75, 47],
1640
- [44, 54, 24, 7, 55, 25],
1641
- [59, 46, 16, 1, 47, 17],
1642
-
1643
- // 35
1644
- [12, 151, 121, 7, 152, 122],
1645
- [12, 75, 47, 26, 76, 48],
1646
- [39, 54, 24, 14, 55, 25],
1647
- [22, 45, 15, 41, 46, 16],
1648
-
1649
- // 36
1650
- [6, 151, 121, 14, 152, 122],
1651
- [6, 75, 47, 34, 76, 48],
1652
- [46, 54, 24, 10, 55, 25],
1653
- [2, 45, 15, 64, 46, 16],
1654
-
1655
- // 37
1656
- [17, 152, 122, 4, 153, 123],
1657
- [29, 74, 46, 14, 75, 47],
1658
- [49, 54, 24, 10, 55, 25],
1659
- [24, 45, 15, 46, 46, 16],
1660
-
1661
- // 38
1662
- [4, 152, 122, 18, 153, 123],
1663
- [13, 74, 46, 32, 75, 47],
1664
- [48, 54, 24, 14, 55, 25],
1665
- [42, 45, 15, 32, 46, 16],
1666
-
1667
- // 39
1668
- [20, 147, 117, 4, 148, 118],
1669
- [40, 75, 47, 7, 76, 48],
1670
- [43, 54, 24, 22, 55, 25],
1671
- [10, 45, 15, 67, 46, 16],
1672
-
1673
- // 40
1674
- [19, 148, 118, 6, 149, 119],
1675
- [18, 75, 47, 31, 76, 48],
1676
- [34, 54, 24, 34, 55, 25],
1677
- [20, 45, 15, 61, 46, 16]
1678
- ];
1679
-
1680
- var qrRSBlock = function(totalCount, dataCount) {
1681
- var _this = {};
1682
- _this.totalCount = totalCount;
1683
- _this.dataCount = dataCount;
1684
- return _this;
1685
- };
1686
-
1687
- var _this = {};
1688
-
1689
- var getRsBlockTable = function(typeNumber, errorCorrectLevel) {
1690
-
1691
- switch(errorCorrectLevel) {
1692
- case QRErrorCorrectLevel.L :
1693
- return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
1694
- case QRErrorCorrectLevel.M :
1695
- return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
1696
- case QRErrorCorrectLevel.Q :
1697
- return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
1698
- case QRErrorCorrectLevel.H :
1699
- return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
1700
- default :
1701
- return undefined;
1702
- }
1703
- };
1704
 
1705
- _this.getRSBlocks = function(typeNumber, errorCorrectLevel) {
 
1706
 
1707
- var rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel);
 
 
1708
 
1709
- if (typeof rsBlock == 'undefined') {
1710
- throw new Error('bad rs block @ typeNumber:' + typeNumber +
1711
- '/errorCorrectLevel:' + errorCorrectLevel);
1712
- }
1713
 
1714
- var length = rsBlock.length / 3;
 
 
1715
 
1716
- var list = new Array();
1717
 
1718
- for (var i = 0; i < length; i += 1) {
 
 
1719
 
1720
- var count = rsBlock[i * 3 + 0];
1721
- var totalCount = rsBlock[i * 3 + 1];
1722
- var dataCount = rsBlock[i * 3 + 2];
1723
 
1724
- for (var j = 0; j < count; j += 1) {
1725
- list.push(qrRSBlock(totalCount, dataCount) );
1726
- }
1727
- }
 
1728
 
1729
- return list;
1730
- };
1731
 
1732
- return _this;
1733
- }();
 
1734
 
1735
- //---------------------------------------------------------------------
1736
- // qrBitBuffer
1737
- //---------------------------------------------------------------------
1738
 
1739
- var qrBitBuffer = function() {
 
1740
 
1741
- var _buffer = new Array();
1742
- var _length = 0;
 
 
 
 
 
 
 
 
 
1743
 
1744
- var _this = {};
1745
 
1746
- _this.getBuffer = function() {
1747
- return _buffer;
1748
- };
1749
 
1750
- _this.getAt = function(index) {
1751
- var bufIndex = Math.floor(index / 8);
1752
- return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
1753
- };
1754
 
1755
- _this.put = function(num, length) {
1756
- for (var i = 0; i < length; i += 1) {
1757
- _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
1758
- }
1759
- };
1760
 
1761
- _this.getLengthInBits = function() {
1762
- return _length;
1763
- };
1764
 
1765
- _this.putBit = function(bit) {
1766
 
1767
- var bufIndex = Math.floor(_length / 8);
1768
- if (_buffer.length <= bufIndex) {
1769
- _buffer.push(0);
1770
- }
1771
 
1772
- if (bit) {
1773
- _buffer[bufIndex] |= (0x80 >>> (_length % 8) );
1774
- }
1775
 
1776
- _length += 1;
1777
- };
1778
 
1779
- return _this;
1780
- };
 
 
 
 
 
1781
 
1782
- //---------------------------------------------------------------------
1783
- // qr8BitByte
1784
- //---------------------------------------------------------------------
1785
 
1786
- var qr8BitByte = function(data) {
1787
 
1788
- var _mode = QRMode.MODE_8BIT_BYTE;
1789
- var _data = data;
1790
- var _bytes = qrcode.stringToBytes(data);
1791
 
1792
- var _this = {};
 
 
 
1793
 
1794
- _this.getMode = function() {
1795
- return _mode;
1796
- };
1797
 
1798
- _this.getLength = function(buffer) {
1799
- return _bytes.length;
1800
- };
1801
 
1802
- _this.write = function(buffer) {
1803
- for (var i = 0; i < _bytes.length; i += 1) {
1804
- buffer.put(_bytes[i], 8);
1805
- }
1806
- };
1807
 
1808
- return _this;
1809
- };
1810
 
1811
- //=====================================================================
1812
- // GIF Support etc.
1813
- //
1814
 
1815
- //---------------------------------------------------------------------
1816
- // byteArrayOutputStream
1817
- //---------------------------------------------------------------------
1818
 
1819
- var byteArrayOutputStream = function() {
 
 
1820
 
1821
- var _bytes = new Array();
 
 
 
1822
 
1823
- var _this = {};
 
 
 
 
 
 
1824
 
1825
- _this.writeByte = function(b) {
1826
- _bytes.push(b & 0xff);
1827
- };
 
 
1828
 
1829
- _this.writeShort = function(i) {
1830
- _this.writeByte(i);
1831
- _this.writeByte(i >>> 8);
1832
- };
1833
 
1834
- _this.writeBytes = function(b, off, len) {
1835
- off = off || 0;
1836
- len = len || b.length;
1837
- for (var i = 0; i < len; i += 1) {
1838
- _this.writeByte(b[i + off]);
1839
- }
1840
- };
 
 
 
 
 
1841
 
1842
- _this.writeString = function(s) {
1843
- for (var i = 0; i < s.length; i += 1) {
1844
- _this.writeByte(s.charCodeAt(i) );
1845
- }
1846
- };
1847
-
1848
- _this.toByteArray = function() {
1849
- return _bytes;
1850
- };
1851
-
1852
- _this.toString = function() {
1853
- var s = '';
1854
- s += '[';
1855
- for (var i = 0; i < _bytes.length; i += 1) {
1856
- if (i > 0) {
1857
- s += ',';
1858
- }
1859
- s += _bytes[i];
1860
- }
1861
- s += ']';
1862
- return s;
1863
- };
1864
 
1865
- return _this;
1866
- };
 
1867
 
1868
- //---------------------------------------------------------------------
1869
- // base64EncodeOutputStream
1870
- //---------------------------------------------------------------------
1871
-
1872
- var base64EncodeOutputStream = function() {
1873
-
1874
- var _buffer = 0;
1875
- var _buflen = 0;
1876
- var _length = 0;
1877
- var _base64 = '';
1878
-
1879
- var _this = {};
1880
-
1881
- var writeEncoded = function(b) {
1882
- _base64 += String.fromCharCode(encode(b & 0x3f) );
1883
- };
1884
-
1885
- var encode = function(n) {
1886
- if (n < 0) {
1887
- // error.
1888
- } else if (n < 26) {
1889
- return 0x41 + n;
1890
- } else if (n < 52) {
1891
- return 0x61 + (n - 26);
1892
- } else if (n < 62) {
1893
- return 0x30 + (n - 52);
1894
- } else if (n == 62) {
1895
- return 0x2b;
1896
- } else if (n == 63) {
1897
- return 0x2f;
1898
- }
1899
- throw new Error('n:' + n);
1900
- };
1901
 
1902
- _this.writeByte = function(n) {
 
 
 
1903
 
1904
- _buffer = (_buffer << 8) | (n & 0xff);
1905
- _buflen += 8;
1906
- _length += 1;
1907
 
1908
- while (_buflen >= 6) {
1909
- writeEncoded(_buffer >>> (_buflen - 6) );
1910
- _buflen -= 6;
1911
- }
1912
- };
1913
 
1914
- _this.flush = function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1915
 
1916
- if (_buflen > 0) {
1917
- writeEncoded(_buffer << (6 - _buflen) );
1918
- _buffer = 0;
1919
- _buflen = 0;
1920
- }
1921
 
1922
- if (_length % 3 != 0) {
1923
- // padding
1924
- var padlen = 3 - _length % 3;
1925
- for (var i = 0; i < padlen; i += 1) {
1926
- _base64 += '=';
1927
- }
1928
- }
1929
- };
1930
 
1931
- _this.toString = function() {
1932
- return _base64;
1933
- };
 
 
1934
 
1935
- return _this;
1936
- };
1937
 
1938
- //---------------------------------------------------------------------
1939
- // base64DecodeInputStream
1940
- //---------------------------------------------------------------------
 
 
1941
 
1942
- var base64DecodeInputStream = function(str) {
 
 
 
 
 
 
 
1943
 
1944
- var _str = str;
1945
- var _pos = 0;
1946
- var _buffer = 0;
1947
- var _buflen = 0;
1948
 
1949
- var _this = {};
 
1950
 
1951
- _this.read = function() {
 
 
1952
 
1953
- while (_buflen < 8) {
1954
 
1955
- if (_pos >= _str.length) {
1956
- if (_buflen == 0) {
1957
- return -1;
1958
- }
1959
- throw new Error('unexpected end of file./' + _buflen);
1960
- }
1961
 
1962
- var c = _str.charAt(_pos);
1963
- _pos += 1;
1964
 
1965
- if (c == '=') {
1966
- _buflen = 0;
1967
- return -1;
1968
- } else if (c.match(/^\s$/) ) {
1969
- // ignore if whitespace.
1970
- continue;
1971
- }
1972
 
1973
- _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );
1974
- _buflen += 6;
1975
- }
1976
 
1977
- var n = (_buffer >>> (_buflen - 8) ) & 0xff;
1978
- _buflen -= 8;
1979
- return n;
1980
- };
1981
-
1982
- var decode = function(c) {
1983
- if (0x41 <= c && c <= 0x5a) {
1984
- return c - 0x41;
1985
- } else if (0x61 <= c && c <= 0x7a) {
1986
- return c - 0x61 + 26;
1987
- } else if (0x30 <= c && c <= 0x39) {
1988
- return c - 0x30 + 52;
1989
- } else if (c == 0x2b) {
1990
- return 62;
1991
- } else if (c == 0x2f) {
1992
- return 63;
1993
- } else {
1994
- throw new Error('c:' + c);
1995
  }
1996
- };
 
1997
 
1998
- return _this;
1999
- };
2000
 
2001
- //---------------------------------------------------------------------
2002
- // gifImage (B/W)
2003
- //---------------------------------------------------------------------
 
 
 
 
2004
 
2005
- var gifImage = function(width, height) {
 
 
2006
 
2007
- var _width = width;
2008
- var _height = height;
2009
- var _data = new Array(width * height);
 
2010
 
2011
- var _this = {};
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2012
 
2013
- _this.setPixel = function(x, y, pixel) {
2014
- _data[y * _width + x] = pixel;
2015
- };
2016
 
2017
- _this.write = function(out) {
 
 
2018
 
2019
- //---------------------------------
2020
- // GIF Signature
2021
 
2022
- out.writeString('GIF87a');
 
 
2023
 
2024
- //---------------------------------
2025
- // Screen Descriptor
2026
 
2027
- out.writeShort(_width);
2028
- out.writeShort(_height);
 
2029
 
2030
- out.writeByte(0x80); // 2bit
2031
- out.writeByte(0);
2032
- out.writeByte(0);
2033
 
2034
- //---------------------------------
2035
- // Global Color Map
2036
 
2037
- // black
2038
- out.writeByte(0x00);
2039
- out.writeByte(0x00);
2040
- out.writeByte(0x00);
2041
 
2042
- // white
2043
- out.writeByte(0xff);
2044
- out.writeByte(0xff);
2045
- out.writeByte(0xff);
2046
 
2047
- //---------------------------------
2048
- // Image Descriptor
2049
 
2050
- out.writeString(',');
2051
- out.writeShort(0);
2052
- out.writeShort(0);
2053
- out.writeShort(_width);
2054
- out.writeShort(_height);
2055
- out.writeByte(0);
2056
 
2057
- //---------------------------------
2058
- // Local Color Map
2059
 
2060
- //---------------------------------
2061
- // Raster Data
 
 
2062
 
2063
- var lzwMinCodeSize = 2;
2064
- var raster = getLZWRaster(lzwMinCodeSize);
 
 
2065
 
2066
- out.writeByte(lzwMinCodeSize);
 
2067
 
2068
- var offset = 0;
 
 
 
 
 
2069
 
2070
- while (raster.length - offset > 255) {
2071
- out.writeByte(255);
2072
- out.writeBytes(raster, offset, 255);
2073
- offset += 255;
2074
- }
2075
 
2076
- out.writeByte(raster.length - offset);
2077
- out.writeBytes(raster, offset, raster.length - offset);
2078
- out.writeByte(0x00);
2079
 
2080
- //---------------------------------
2081
- // GIF Terminator
2082
- out.writeString(';');
2083
- };
2084
 
2085
- var bitOutputStream = function(out) {
2086
 
2087
- var _out = out;
2088
- var _bitLength = 0;
2089
- var _bitBuffer = 0;
2090
 
2091
- var _this = {};
 
 
 
 
2092
 
2093
- _this.write = function(data, length) {
 
 
2094
 
2095
- if ( (data >>> length) != 0) {
2096
- throw new Error('length over');
2097
- }
 
2098
 
2099
- while (_bitLength + length >= 8) {
2100
- _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );
2101
- length -= (8 - _bitLength);
2102
- data >>>= (8 - _bitLength);
2103
- _bitBuffer = 0;
2104
- _bitLength = 0;
2105
- }
2106
 
2107
- _bitBuffer = (data << _bitLength) | _bitBuffer;
2108
- _bitLength = _bitLength + length;
2109
- };
2110
 
2111
- _this.flush = function() {
2112
- if (_bitLength > 0) {
2113
- _out.writeByte(_bitBuffer);
2114
- }
2115
- };
2116
 
2117
- return _this;
2118
- };
2119
 
2120
- var getLZWRaster = function(lzwMinCodeSize) {
 
 
2121
 
2122
- var clearCode = 1 << lzwMinCodeSize;
2123
- var endCode = (1 << lzwMinCodeSize) + 1;
2124
- var bitLength = lzwMinCodeSize + 1;
 
 
 
 
2125
 
2126
- // Setup LZWTable
2127
- var table = lzwTable();
 
2128
 
2129
- for (var i = 0; i < clearCode; i += 1) {
2130
- table.add(String.fromCharCode(i) );
2131
- }
2132
- table.add(String.fromCharCode(clearCode) );
2133
- table.add(String.fromCharCode(endCode) );
2134
 
2135
- var byteOut = byteArrayOutputStream();
2136
- var bitOut = bitOutputStream(byteOut);
2137
 
2138
- // clear code
2139
- bitOut.write(clearCode, bitLength);
2140
 
2141
- var dataIndex = 0;
 
 
2142
 
2143
- var s = String.fromCharCode(_data[dataIndex]);
2144
- dataIndex += 1;
2145
 
2146
- while (dataIndex < _data.length) {
 
 
 
 
2147
 
2148
- var c = String.fromCharCode(_data[dataIndex]);
2149
- dataIndex += 1;
2150
 
2151
- if (table.contains(s + c) ) {
 
2152
 
2153
- s = s + c;
2154
 
2155
- } else {
 
2156
 
2157
- bitOut.write(table.indexOf(s), bitLength);
2158
 
2159
- if (table.size() < 0xfff) {
 
2160
 
2161
- if (table.size() == (1 << bitLength) ) {
2162
- bitLength += 1;
2163
- }
2164
 
2165
- table.add(s + c);
2166
- }
2167
 
2168
- s = c;
2169
- }
2170
- }
2171
 
2172
  bitOut.write(table.indexOf(s), bitLength);
2173
 
2174
- // end code
2175
- bitOut.write(endCode, bitLength);
2176
 
2177
- bitOut.flush();
 
 
2178
 
2179
- return byteOut.toByteArray();
2180
- };
2181
 
2182
- var lzwTable = function() {
 
 
2183
 
2184
- var _map = {};
2185
- var _size = 0;
2186
 
2187
- var _this = {};
 
2188
 
2189
- _this.add = function(key) {
2190
- if (_this.contains(key) ) {
2191
- throw new Error('dup key:' + key);
2192
- }
2193
- _map[key] = _size;
2194
- _size += 1;
2195
- };
2196
 
2197
- _this.size = function() {
2198
- return _size;
2199
- };
2200
 
2201
- _this.indexOf = function(key) {
2202
- return _map[key];
2203
- };
2204
 
2205
- _this.contains = function(key) {
2206
- return typeof _map[key] != 'undefined';
2207
- };
2208
 
2209
- return _this;
2210
- };
2211
 
2212
- return _this;
 
 
 
 
 
2213
  };
2214
 
2215
- var createImgTag = function(width, height, getPixel, alt) {
2216
-
2217
- var gif = gifImage(width, height);
2218
- for (var y = 0; y < height; y += 1) {
2219
- for (var x = 0; x < width; x += 1) {
2220
- gif.setPixel(x, y, getPixel(x, y) );
2221
- }
2222
- }
2223
 
2224
- var b = byteArrayOutputStream();
2225
- gif.write(b);
 
2226
 
2227
- var base64 = base64EncodeOutputStream();
2228
- var bytes = b.toByteArray();
2229
- for (var i = 0; i < bytes.length; i += 1) {
2230
- base64.writeByte(bytes[i]);
2231
- }
2232
- base64.flush();
2233
 
2234
- var img = '';
2235
- img += '<img';
2236
- img += '\u0020src="';
2237
- img += 'data:image/gif;base64,';
2238
- img += base64;
2239
- img += '"';
2240
- img += '\u0020width="';
2241
- img += width;
2242
- img += '"';
2243
- img += '\u0020height="';
2244
- img += height;
2245
- img += '"';
2246
- if (alt) {
2247
- img += '\u0020alt="';
2248
- img += alt;
2249
- img += '"';
2250
- }
2251
- img += '/>';
2252
 
2253
- return img;
2254
- };
2255
 
2256
- //---------------------------------------------------------------------
2257
- // returns qrcode function.
 
 
 
 
 
2258
 
2259
- return qrcode;
2260
- }();
2261
 
2262
- (function (factory) {
2263
- if (typeof define === 'function' && define.amd) {
2264
- define([], factory);
2265
- } else if (typeof exports === 'object') {
2266
- module.exports = factory();
2267
- }
2268
- }(function () {
2269
- return qrcode;
2270
- }));
2271
- //---------------------------------------------------------------------
2272
- //
2273
- // QR Code Generator for JavaScript UTF8 Support (optional)
2274
- //
2275
- // Copyright (c) 2011 Kazuhiko Arase
2276
- //
2277
- // URL: http://www.d-project.com/
2278
- //
2279
- // Licensed under the MIT license:
2280
- // http://www.opensource.org/licenses/mit-license.php
2281
- //
2282
- // The word 'QR Code' is registered trademark of
2283
- // DENSO WAVE INCORPORATED
2284
- // http://www.denso-wave.com/qrcode/faqpatent-e.html
2285
- //
2286
- //---------------------------------------------------------------------
2287
-
2288
- !function(qrcode) {
2289
-
2290
- //---------------------------------------------------------------------
2291
- // overwrite qrcode.stringToBytes
2292
- //---------------------------------------------------------------------
2293
-
2294
- qrcode.stringToBytes = function(s) {
2295
- // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
2296
- function toUTF8Array(str) {
2297
- var utf8 = [];
2298
- for (var i=0; i < str.length; i++) {
2299
- var charcode = str.charCodeAt(i);
2300
- if (charcode < 0x80) utf8.push(charcode);
2301
- else if (charcode < 0x800) {
2302
- utf8.push(0xc0 | (charcode >> 6),
2303
- 0x80 | (charcode & 0x3f));
2304
- }
2305
- else if (charcode < 0xd800 || charcode >= 0xe000) {
2306
- utf8.push(0xe0 | (charcode >> 12),
2307
- 0x80 | ((charcode>>6) & 0x3f),
2308
- 0x80 | (charcode & 0x3f));
2309
- }
2310
- // surrogate pair
2311
- else {
2312
- i++;
2313
- // UTF-16 encodes 0x10000-0x10FFFF by
2314
- // subtracting 0x10000 and splitting the
2315
- // 20 bits of 0x0-0xFFFFF into two halves
2316
- charcode = 0x10000 + (((charcode & 0x3ff)<<10)
2317
- | (str.charCodeAt(i) & 0x3ff));
2318
- utf8.push(0xf0 | (charcode >>18),
2319
- 0x80 | ((charcode>>12) & 0x3f),
2320
- 0x80 | ((charcode>>6) & 0x3f),
2321
- 0x80 | (charcode & 0x3f));
2322
- }
2323
- }
2324
- return utf8;
2325
  }
2326
- return toUTF8Array(s);
2327
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2328
 
2329
- }(qrcode);
2330
 
2331
- return qrcode; // eslint-disable-line no-undef
2332
- }()));
 
1
+ /*! jquery-qrcode v0.17.0 - https://larsjung.de/jquery-qrcode/ */
2
+ (function webpackUniversalModuleDefinition(root, factory) {
3
+ if(typeof exports === 'object' && typeof module === 'object')
4
+ module.exports = factory();
5
+ else if(typeof define === 'function' && define.amd)
6
+ define("jquery-qrcode", [], factory);
7
+ else if(typeof exports === 'object')
8
+ exports["jquery-qrcode"] = factory();
9
+ else
10
+ root["jquery-qrcode"] = factory();
11
+ })((typeof self !== 'undefined' ? self : this), function() {
12
+ return /******/ (function(modules) { // webpackBootstrap
13
+ /******/ // The module cache
14
+ /******/ var installedModules = {};
15
+ /******/
16
+ /******/ // The require function
17
+ /******/ function __webpack_require__(moduleId) {
18
+ /******/
19
+ /******/ // Check if module is in cache
20
+ /******/ if(installedModules[moduleId]) {
21
+ /******/ return installedModules[moduleId].exports;
22
+ /******/ }
23
+ /******/ // Create a new module (and put it into the cache)
24
+ /******/ var module = installedModules[moduleId] = {
25
+ /******/ i: moduleId,
26
+ /******/ l: false,
27
+ /******/ exports: {}
28
+ /******/ };
29
+ /******/
30
+ /******/ // Execute the module function
31
+ /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
32
+ /******/
33
+ /******/ // Flag the module as loaded
34
+ /******/ module.l = true;
35
+ /******/
36
+ /******/ // Return the exports of the module
37
+ /******/ return module.exports;
38
+ /******/ }
39
+ /******/
40
+ /******/
41
+ /******/ // expose the modules object (__webpack_modules__)
42
+ /******/ __webpack_require__.m = modules;
43
+ /******/
44
+ /******/ // expose the module cache
45
+ /******/ __webpack_require__.c = installedModules;
46
+ /******/
47
+ /******/ // define getter function for harmony exports
48
+ /******/ __webpack_require__.d = function(exports, name, getter) {
49
+ /******/ if(!__webpack_require__.o(exports, name)) {
50
+ /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
51
+ /******/ }
52
+ /******/ };
53
+ /******/
54
+ /******/ // define __esModule on exports
55
+ /******/ __webpack_require__.r = function(exports) {
56
+ /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
57
+ /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
58
+ /******/ }
59
+ /******/ Object.defineProperty(exports, '__esModule', { value: true });
60
+ /******/ };
61
+ /******/
62
+ /******/ // create a fake namespace object
63
+ /******/ // mode & 1: value is a module id, require it
64
+ /******/ // mode & 2: merge all properties of value into the ns
65
+ /******/ // mode & 4: return value when already ns object
66
+ /******/ // mode & 8|1: behave like require
67
+ /******/ __webpack_require__.t = function(value, mode) {
68
+ /******/ if(mode & 1) value = __webpack_require__(value);
69
+ /******/ if(mode & 8) return value;
70
+ /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
71
+ /******/ var ns = Object.create(null);
72
+ /******/ __webpack_require__.r(ns);
73
+ /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
74
+ /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
75
+ /******/ return ns;
76
+ /******/ };
77
+ /******/
78
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
79
+ /******/ __webpack_require__.n = function(module) {
80
+ /******/ var getter = module && module.__esModule ?
81
+ /******/ function getDefault() { return module['default']; } :
82
+ /******/ function getModuleExports() { return module; };
83
+ /******/ __webpack_require__.d(getter, 'a', getter);
84
+ /******/ return getter;
85
+ /******/ };
86
+ /******/
87
+ /******/ // Object.prototype.hasOwnProperty.call
88
+ /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
89
+ /******/
90
+ /******/ // __webpack_public_path__
91
+ /******/ __webpack_require__.p = "";
92
+ /******/
93
+ /******/
94
+ /******/ // Load entry module and return exports
95
+ /******/ return __webpack_require__(__webpack_require__.s = 0);
96
+ /******/ })
97
+ /************************************************************************/
98
+ /******/ ([
99
+ /* 0 */
100
+ /***/ (function(module, exports, __webpack_require__) {
101
+
102
+ /* WEBPACK VAR INJECTION */(function(global) {var WIN = global.window;
103
+ var JQ = WIN.jQuery; // Check if canvas is available in the browser (as Modernizr does)
104
+
105
+ var HAS_CANVAS = function () {
106
+ var el = WIN.document.createElement('canvas');
107
+ return !!(el.getContext && el.getContext('2d'));
108
+ }();
109
+
110
+ var is_img_el = function is_img_el(x) {
111
+ return x && typeof x.tagName === 'string' && x.tagName.toUpperCase() === 'IMG';
112
+ }; // Wrapper for the original QR code generator.
113
+
114
+
115
+ var create_qrcode = function create_qrcode(text, level, version, quiet) {
116
+ var qr = {};
117
+
118
+ var qr_gen = __webpack_require__(2);
119
+
120
+ qr_gen.stringToBytes = qr_gen.stringToBytesFuncs['UTF-8'];
121
+ var vqr = qr_gen(version, level);
122
+ vqr.addData(text);
123
+ vqr.make();
124
+ quiet = quiet || 0;
125
+ var module_count = vqr.getModuleCount();
126
+ var quiet_module_count = module_count + 2 * quiet;
127
+
128
+ var is_dark = function is_dark(row, col) {
129
+ row -= quiet;
130
+ col -= quiet;
131
+ return row >= 0 && row < module_count && col >= 0 && col < module_count && vqr.isDark(row, col);
132
+ };
133
+
134
+ var add_blank = function add_blank(l, t, r, b) {
135
+ var prev_is_dark = qr.is_dark;
136
+ var module_size = 1 / quiet_module_count;
137
+
138
+ qr.is_dark = function (row, col) {
139
+ var ml = col * module_size;
140
+ var mt = row * module_size;
141
+ var mr = ml + module_size;
142
+ var mb = mt + module_size;
143
+ return prev_is_dark(row, col) && (l > mr || ml > r || t > mb || mt > b);
144
+ };
145
+ };
146
+
147
+ qr.text = text;
148
+ qr.level = level;
149
+ qr.version = version;
150
+ qr.module_count = quiet_module_count;
151
+ qr.is_dark = is_dark;
152
+ qr.add_blank = add_blank;
153
+ return qr;
154
+ }; // Returns a minimal QR code for the given text starting with version `min_ver`.
155
+ // Returns `undefined` if `text` is too long to be encoded in `max_ver`.
156
+
157
+
158
+ var create_min_qrcode = function create_min_qrcode(text, level, min_ver, max_ver, quiet) {
159
+ min_ver = Math.max(1, min_ver || 1);
160
+ max_ver = Math.min(40, max_ver || 40);
161
+
162
+ for (var ver = min_ver; ver <= max_ver; ver += 1) {
163
+ try {
164
+ return create_qrcode(text, level, ver, quiet);
165
+ } catch (err) {
166
+ /* empty */
167
+ }
168
+ }
169
+
170
+ return undefined;
171
+ };
172
+
173
+ var draw_background_label = function draw_background_label(qr, context, settings) {
174
+ var size = settings.size;
175
+ var font = 'bold ' + settings.mSize * size + 'px ' + settings.fontname;
176
+ var ctx = JQ('<canvas/>')[0].getContext('2d');
177
+ ctx.font = font;
178
+ var w = ctx.measureText(settings.label).width;
179
+ var sh = settings.mSize;
180
+ var sw = w / size;
181
+ var sl = (1 - sw) * settings.mPosX;
182
+ var st = (1 - sh) * settings.mPosY;
183
+ var sr = sl + sw;
184
+ var sb = st + sh;
185
+ var pad = 0.01;
186
+
187
+ if (settings.mode === 1) {
188
+ // Strip
189
+ qr.add_blank(0, st - pad, size, sb + pad);
190
+ } else {
191
+ // Box
192
+ qr.add_blank(sl - pad, st - pad, sr + pad, sb + pad);
193
+ }
194
+
195
+ context.fillStyle = settings.fontcolor;
196
+ context.font = font;
197
+ context.fillText(settings.label, sl * size, st * size + 0.75 * settings.mSize * size);
198
+ };
199
+
200
+ var draw_background_img = function draw_background_img(qr, context, settings) {
201
+ var size = settings.size;
202
+ var w = settings.image.naturalWidth || 1;
203
+ var h = settings.image.naturalHeight || 1;
204
+ var sh = settings.mSize;
205
+ var sw = sh * w / h;
206
+ var sl = (1 - sw) * settings.mPosX;
207
+ var st = (1 - sh) * settings.mPosY;
208
+ var sr = sl + sw;
209
+ var sb = st + sh;
210
+ var pad = 0.01;
211
+
212
+ if (settings.mode === 3) {
213
+ // Strip
214
+ qr.add_blank(0, st - pad, size, sb + pad);
215
+ } else {
216
+ // Box
217
+ qr.add_blank(sl - pad, st - pad, sr + pad, sb + pad);
218
+ }
219
+
220
+ context.drawImage(settings.image, sl * size, st * size, sw * size, sh * size);
221
+ };
222
+
223
+ var draw_background = function draw_background(qr, context, settings) {
224
+ if (is_img_el(settings.background)) {
225
+ context.drawImage(settings.background, 0, 0, settings.size, settings.size);
226
+ } else if (settings.background) {
227
+ context.fillStyle = settings.background;
228
+ context.fillRect(settings.left, settings.top, settings.size, settings.size);
229
+ }
230
+
231
+ var mode = settings.mode;
232
+
233
+ if (mode === 1 || mode === 2) {
234
+ draw_background_label(qr, context, settings);
235
+ } else if (is_img_el(settings.image) && (mode === 3 || mode === 4)) {
236
+ draw_background_img(qr, context, settings);
237
+ }
238
+ };
239
+
240
+ var draw_modules_default = function draw_modules_default(qr, context, settings, left, top, width, row, col) {
241
+ if (qr.is_dark(row, col)) {
242
+ context.rect(left, top, width, width);
243
+ }
244
+ };
245
+
246
+ var draw_modules_rounded_dark = function draw_modules_rounded_dark(ctx, l, t, r, b, rad, nw, ne, se, sw) {
247
+ if (nw) {
248
+ ctx.moveTo(l + rad, t);
249
+ } else {
250
+ ctx.moveTo(l, t);
251
+ }
252
+
253
+ if (ne) {
254
+ ctx.lineTo(r - rad, t);
255
+ ctx.arcTo(r, t, r, b, rad);
256
+ } else {
257
+ ctx.lineTo(r, t);
258
+ }
259
+
260
+ if (se) {
261
+ ctx.lineTo(r, b - rad);
262
+ ctx.arcTo(r, b, l, b, rad);
263
+ } else {
264
+ ctx.lineTo(r, b);
265
+ }
266
+
267
+ if (sw) {
268
+ ctx.lineTo(l + rad, b);
269
+ ctx.arcTo(l, b, l, t, rad);
270
+ } else {
271
+ ctx.lineTo(l, b);
272
+ }
273
+
274
+ if (nw) {
275
+ ctx.lineTo(l, t + rad);
276
+ ctx.arcTo(l, t, r, t, rad);
277
+ } else {
278
+ ctx.lineTo(l, t);
279
+ }
280
+ };
281
+
282
+ var draw_modules_rounded_light = function draw_modules_rounded_light(ctx, l, t, r, b, rad, nw, ne, se, sw) {
283
+ if (nw) {
284
+ ctx.moveTo(l + rad, t);
285
+ ctx.lineTo(l, t);
286
+ ctx.lineTo(l, t + rad);
287
+ ctx.arcTo(l, t, l + rad, t, rad);
288
+ }
289
+
290
+ if (ne) {
291
+ ctx.moveTo(r - rad, t);
292
+ ctx.lineTo(r, t);
293
+ ctx.lineTo(r, t + rad);
294
+ ctx.arcTo(r, t, r - rad, t, rad);
295
+ }
296
+
297
+ if (se) {
298
+ ctx.moveTo(r - rad, b);
299
+ ctx.lineTo(r, b);
300
+ ctx.lineTo(r, b - rad);
301
+ ctx.arcTo(r, b, r - rad, b, rad);
302
+ }
303
+
304
+ if (sw) {
305
+ ctx.moveTo(l + rad, b);
306
+ ctx.lineTo(l, b);
307
+ ctx.lineTo(l, b - rad);
308
+ ctx.arcTo(l, b, l + rad, b, rad);
309
+ }
310
+ };
311
+
312
+ var draw_modules_rounded = function draw_modules_rounded(qr, context, settings, left, top, width, row, col) {
313
+ var is_dark = qr.is_dark;
314
+ var right = left + width;
315
+ var bottom = top + width;
316
+ var radius = settings.radius * width;
317
+ var rowT = row - 1;
318
+ var rowB = row + 1;
319
+ var colL = col - 1;
320
+ var colR = col + 1;
321
+ var center = is_dark(row, col);
322
+ var northwest = is_dark(rowT, colL);
323
+ var north = is_dark(rowT, col);
324
+ var northeast = is_dark(rowT, colR);
325
+ var east = is_dark(row, colR);
326
+ var southeast = is_dark(rowB, colR);
327
+ var south = is_dark(rowB, col);
328
+ var southwest = is_dark(rowB, colL);
329
+ var west = is_dark(row, colL);
330
+
331
+ if (center) {
332
+ draw_modules_rounded_dark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west);
333
+ } else {
334
+ draw_modules_rounded_light(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest);
335
+ }
336
+ };
337
+
338
+ var draw_modules = function draw_modules(qr, context, settings) {
339
+ var module_count = qr.module_count;
340
+ var module_size = settings.size / module_count;
341
+ var fn = draw_modules_default;
342
+ var row;
343
+ var col;
344
+
345
+ if (settings.radius > 0 && settings.radius <= 0.5) {
346
+ fn = draw_modules_rounded;
347
+ }
348
+
349
+ context.beginPath();
350
+
351
+ for (row = 0; row < module_count; row += 1) {
352
+ for (col = 0; col < module_count; col += 1) {
353
+ var l = settings.left + col * module_size;
354
+ var t = settings.top + row * module_size;
355
+ var w = module_size;
356
+ fn(qr, context, settings, l, t, w, row, col);
357
+ }
358
+ }
359
+
360
+ if (is_img_el(settings.fill)) {
361
+ context.strokeStyle = 'rgba(0,0,0,0.5)';
362
+ context.lineWidth = 2;
363
+ context.stroke();
364
+ var prev = context.globalCompositeOperation;
365
+ context.globalCompositeOperation = 'destination-out';
366
+ context.fill();
367
+ context.globalCompositeOperation = prev;
368
+ context.clip();
369
+ context.drawImage(settings.fill, 0, 0, settings.size, settings.size);
370
+ context.restore();
371
+ } else {
372
+ context.fillStyle = settings.fill;
373
+ context.fill();
374
+ }
375
+ }; // Draws QR code to the given `canvas` and returns it.
376
+
377
+
378
+ var draw_on_canvas = function draw_on_canvas(canvas, settings) {
379
+ var qr = create_min_qrcode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
380
+
381
+ if (!qr) {
382
+ return null;
383
+ }
384
+
385
+ var $canvas = JQ(canvas).data('qrcode', qr);
386
+ var context = $canvas[0].getContext('2d');
387
+ draw_background(qr, context, settings);
388
+ draw_modules(qr, context, settings);
389
+ return $canvas;
390
+ }; // Returns a `canvas` element representing the QR code for the given settings.
391
+
392
+
393
+ var create_canvas = function create_canvas(settings) {
394
+ var $canvas = JQ('<canvas/>').attr('width', settings.size).attr('height', settings.size);
395
+ return draw_on_canvas($canvas, settings);
396
+ }; // Returns an `image` element representing the QR code for the given settings.
397
+
398
+
399
+ var create_img = function create_img(settings) {
400
+ return JQ('<img/>').attr('src', create_canvas(settings)[0].toDataURL('image/png'));
401
+ }; // Returns a `div` element representing the QR code for the given settings.
402
+
403
+
404
+ var create_div = function create_div(settings) {
405
+ var qr = create_min_qrcode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
406
+
407
+ if (!qr) {
408
+ return null;
409
+ } // some shortcuts to improve compression
410
+
411
+
412
+ var settings_size = settings.size;
413
+ var settings_bgColor = settings.background;
414
+ var math_floor = Math.floor;
415
+ var module_count = qr.module_count;
416
+ var module_size = math_floor(settings_size / module_count);
417
+ var offset = math_floor(0.5 * (settings_size - module_size * module_count));
418
+ var row;
419
+ var col;
420
+ var container_css = {
421
+ position: 'relative',
422
+ left: 0,
423
+ top: 0,
424
+ padding: 0,
425
+ margin: 0,
426
+ width: settings_size,
427
+ height: settings_size
428
+ };
429
+ var dark_css = {
430
+ position: 'absolute',
431
+ padding: 0,
432
+ margin: 0,
433
+ width: module_size,
434
+ height: module_size,
435
+ 'background-color': settings.fill
436
+ };
437
+ var $div = JQ('<div/>').data('qrcode', qr).css(container_css);
438
+
439
+ if (settings_bgColor) {
440
+ $div.css('background-color', settings_bgColor);
441
+ }
442
+
443
+ for (row = 0; row < module_count; row += 1) {
444
+ for (col = 0; col < module_count; col += 1) {
445
+ if (qr.is_dark(row, col)) {
446
+ JQ('<div/>').css(dark_css).css({
447
+ left: offset + col * module_size,
448
+ top: offset + row * module_size
449
+ }).appendTo($div);
450
+ }
451
+ }
452
+ }
453
+
454
+ return $div;
455
+ };
456
+
457
+ var create_html = function create_html(settings) {
458
+ if (HAS_CANVAS && settings.render === 'canvas') {
459
+ return create_canvas(settings);
460
+ } else if (HAS_CANVAS && settings.render === 'image') {
461
+ return create_img(settings);
462
+ }
463
+
464
+ return create_div(settings);
465
+ };
466
+
467
+ var DEFAULTS = {
468
+ // render method: `'canvas'`, `'image'` or `'div'`
469
+ render: 'canvas',
470
+ // version range somewhere in 1 .. 40
471
+ minVersion: 1,
472
+ maxVersion: 40,
473
+ // error correction level: `'L'`, `'M'`, `'Q'` or `'H'`
474
+ ecLevel: 'L',
475
+ // offset in pixel if drawn onto existing canvas
476
+ left: 0,
477
+ top: 0,
478
+ // size in pixel
479
+ size: 200,
480
+ // code color or image element
481
+ fill: '#000',
482
+ // background color or image element, `null` for transparent background
483
+ background: '#fff',
484
+ // content
485
+ text: 'no text',
486
+ // corner radius relative to module width: 0.0 .. 0.5
487
+ radius: 0,
488
+ // quiet zone in modules
489
+ quiet: 0,
490
+ // modes
491
+ // 0: normal
492
+ // 1: label strip
493
+ // 2: label box
494
+ // 3: image strip
495
+ // 4: image box
496
+ mode: 0,
497
+ mSize: 0.1,
498
+ mPosX: 0.5,
499
+ mPosY: 0.5,
500
+ label: 'no label',
501
+ fontname: 'sans',
502
+ fontcolor: '#000',
503
+ image: null
504
+ };
505
+
506
+ JQ.fn.qrcode = module.exports = function main(options) {
507
+ var settings = JQ.extend({}, DEFAULTS, options);
508
+ return this.each(function (idx, el) {
509
+ if (el.nodeName.toLowerCase() === 'canvas') {
510
+ draw_on_canvas(el, settings);
511
+ } else {
512
+ JQ(el).append(create_html(settings));
513
+ }
514
+ });
515
+ };
516
+ /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
517
+
518
+ /***/ }),
519
+ /* 1 */
520
+ /***/ (function(module, exports) {
521
+
522
+ var g;
523
+
524
+ // This works in non-strict mode
525
+ g = (function() {
526
+ return this;
527
+ })();
528
+
529
+ try {
530
+ // This works if eval is allowed (see CSP)
531
+ g = g || new Function("return this")();
532
+ } catch (e) {
533
+ // This works if the window reference is available
534
+ if (typeof window === "object") g = window;
535
+ }
536
+
537
+ // g can still be undefined, but nothing to do about it...
538
+ // We return undefined, instead of nothing here, so it's
539
+ // easier to handle this case. if(!global) { ...}
540
+
541
+ module.exports = g;
542
+
543
+
544
+ /***/ }),
545
+ /* 2 */
546
+ /***/ (function(module, exports, __webpack_require__) {
547
+
548
+ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;//---------------------------------------------------------------------
549
+ //
550
+ // QR Code Generator for JavaScript
551
+ //
552
+ // Copyright (c) 2009 Kazuhiko Arase
553
+ //
554
+ // URL: http://www.d-project.com/
555
+ //
556
+ // Licensed under the MIT license:
557
+ // http://www.opensource.org/licenses/mit-license.php
558
+ //
559
+ // The word 'QR Code' is registered trademark of
560
+ // DENSO WAVE INCORPORATED
561
+ // http://www.denso-wave.com/qrcode/faqpatent-e.html
562
+ //
563
+ //---------------------------------------------------------------------
564
+
565
+ var qrcode = function() {
566
+
567
+ //---------------------------------------------------------------------
568
+ // qrcode
569
+ //---------------------------------------------------------------------
570
+
571
+ /**
572
+ * qrcode
573
+ * @param typeNumber 1 to 40
574
+ * @param errorCorrectionLevel 'L','M','Q','H'
575
+ */
576
+ var qrcode = function(typeNumber, errorCorrectionLevel) {
577
+
578
+ var PAD0 = 0xEC;
579
+ var PAD1 = 0x11;
580
+
581
+ var _typeNumber = typeNumber;
582
+ var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel];
583
+ var _modules = null;
584
+ var _moduleCount = 0;
585
+ var _dataCache = null;
586
+ var _dataList = [];
587
+
588
+ var _this = {};
589
+
590
+ var makeImpl = function(test, maskPattern) {
591
+
592
+ _moduleCount = _typeNumber * 4 + 17;
593
+ _modules = function(moduleCount) {
594
+ var modules = new Array(moduleCount);
595
+ for (var row = 0; row < moduleCount; row += 1) {
596
+ modules[row] = new Array(moduleCount);
597
+ for (var col = 0; col < moduleCount; col += 1) {
598
+ modules[row][col] = null;
599
+ }
600
+ }
601
+ return modules;
602
+ }(_moduleCount);
603
+
604
+ setupPositionProbePattern(0, 0);
605
+ setupPositionProbePattern(_moduleCount - 7, 0);
606
+ setupPositionProbePattern(0, _moduleCount - 7);
607
+ setupPositionAdjustPattern();
608
+ setupTimingPattern();
609
+ setupTypeInfo(test, maskPattern);
610
+
611
+ if (_typeNumber >= 7) {
612
+ setupTypeNumber(test);
613
+ }
614
 
615
+ if (_dataCache == null) {
616
+ _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList);
617
+ }
618
 
619
+ mapData(_dataCache, maskPattern);
620
+ };
 
 
 
621
 
622
+ var setupPositionProbePattern = function(row, col) {
 
 
623
 
624
+ for (var r = -1; r <= 7; r += 1) {
 
 
625
 
626
+ if (row + r <= -1 || _moduleCount <= row + r) continue;
627
 
628
+ for (var c = -1; c <= 7; c += 1) {
 
629
 
630
+ if (col + c <= -1 || _moduleCount <= col + c) continue;
 
 
631
 
632
+ if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
633
+ || (0 <= c && c <= 6 && (r == 0 || r == 6) )
634
+ || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
635
+ _modules[row + r][col + c] = true;
636
+ } else {
637
+ _modules[row + r][col + c] = false;
638
+ }
639
  }
640
+ }
641
+ };
642
+
643
+ var getBestMaskPattern = function() {
644
 
645
+ var minLostPoint = 0;
646
+ var pattern = 0;
 
647
 
648
+ for (var i = 0; i < 8; i += 1) {
 
 
 
 
649
 
650
+ makeImpl(true, i);
651
+
652
+ var lostPoint = QRUtil.getLostPoint(_this);
653
+
654
+ if (i == 0 || minLostPoint > lostPoint) {
655
+ minLostPoint = lostPoint;
656
+ pattern = i;
657
  }
658
+ }
659
 
660
+ return pattern;
661
+ };
 
 
 
 
662
 
663
+ var setupTimingPattern = function() {
 
664
 
665
+ for (var r = 8; r < _moduleCount - 8; r += 1) {
666
+ if (_modules[r][6] != null) {
667
+ continue;
 
 
 
 
 
 
668
  }
669
+ _modules[r][6] = (r % 2 == 0);
670
+ }
671
 
672
+ for (var c = 8; c < _moduleCount - 8; c += 1) {
673
+ if (_modules[6][c] != null) {
674
+ continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
675
  }
676
+ _modules[6][c] = (c % 2 == 0);
677
+ }
678
+ };
679
 
680
+ var setupPositionAdjustPattern = function() {
 
 
 
681
 
682
+ var pos = QRUtil.getPatternPosition(_typeNumber);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
683
 
684
+ for (var i = 0; i < pos.length; i += 1) {
 
685
 
686
+ for (var j = 0; j < pos.length; j += 1) {
 
 
 
 
 
 
687
 
688
+ var row = pos[i];
689
+ var col = pos[j];
 
 
 
 
 
690
 
691
+ if (_modules[row][col] != null) {
692
+ continue;
693
+ }
 
 
694
 
695
+ for (var r = -2; r <= 2; r += 1) {
 
 
 
 
 
696
 
697
+ for (var c = -2; c <= 2; c += 1) {
 
 
 
 
 
698
 
699
+ if (r == -2 || r == 2 || c == -2 || c == 2
700
+ || (r == 0 && c == 0) ) {
701
+ _modules[row + r][col + c] = true;
702
+ } else {
703
+ _modules[row + r][col + c] = false;
704
+ }
705
+ }
706
+ }
707
  }
708
+ }
709
+ };
710
+
711
+ var setupTypeNumber = function(test) {
712
+
713
+ var bits = QRUtil.getBCHTypeNumber(_typeNumber);
714
 
715
+ for (var i = 0; i < 18; i += 1) {
716
+ var mod = (!test && ( (bits >> i) & 1) == 1);
717
+ _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
718
+ }
719
+
720
+ for (var i = 0; i < 18; i += 1) {
721
+ var mod = (!test && ( (bits >> i) & 1) == 1);
722
+ _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
723
+ }
724
+ };
725
+
726
+ var setupTypeInfo = function(test, maskPattern) {
727
+
728
+ var data = (_errorCorrectionLevel << 3) | maskPattern;
729
+ var bits = QRUtil.getBCHTypeInfo(data);
730
+
731
+ // vertical
732
+ for (var i = 0; i < 15; i += 1) {
733
+
734
+ var mod = (!test && ( (bits >> i) & 1) == 1);
735
+
736
+ if (i < 6) {
737
+ _modules[i][8] = mod;
738
+ } else if (i < 8) {
739
+ _modules[i + 1][8] = mod;
740
  } else {
741
+ _modules[_moduleCount - 15 + i][8] = mod;
742
  }
743
+ }
744
+
745
+ // horizontal
746
+ for (var i = 0; i < 15; i += 1) {
747
 
748
+ var mod = (!test && ( (bits >> i) & 1) == 1);
749
+
750
+ if (i < 8) {
751
+ _modules[8][_moduleCount - i - 1] = mod;
752
+ } else if (i < 9) {
753
+ _modules[8][15 - i - 1 + 1] = mod;
754
  } else {
755
+ _modules[8][15 - i - 1] = mod;
756
  }
757
+ }
758
 
759
+ // fixed module
760
+ _modules[_moduleCount - 8][8] = (!test);
761
+ };
 
 
 
 
762
 
763
+ var mapData = function(data, maskPattern) {
 
 
 
 
 
764
 
765
+ var inc = -1;
766
+ var row = _moduleCount - 1;
767
+ var bitIndex = 7;
768
+ var byteIndex = 0;
769
+ var maskFunc = QRUtil.getMaskFunction(maskPattern);
 
770
 
771
+ for (var col = _moduleCount - 1; col > 0; col -= 2) {
 
 
 
 
 
 
772
 
773
+ if (col == 6) col -= 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
 
775
+ while (true) {
 
 
 
 
 
776
 
777
+ for (var c = 0; c < 2; c += 1) {
778
+
779
+ if (_modules[row][col - c] == null) {
780
+
781
+ var dark = false;
782
 
783
+ if (byteIndex < data.length) {
784
+ dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
785
+ }
786
+
787
+ var mask = maskFunc(row, col - c);
788
+
789
+ if (mask) {
790
+ dark = !dark;
791
+ }
792
+
793
+ _modules[row][col - c] = dark;
794
+ bitIndex -= 1;
795
 
796
+ if (bitIndex == -1) {
797
+ byteIndex += 1;
798
+ bitIndex = 7;
799
+ }
800
  }
801
+ }
802
+
803
+ row += inc;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
804
 
805
+ if (row < 0 || _moduleCount <= row) {
806
+ row -= inc;
807
+ inc = -inc;
808
+ break;
809
+ }
810
  }
811
+ }
812
+ };
813
 
814
+ var createBytes = function(buffer, rsBlocks) {
 
815
 
816
+ var offset = 0;
 
817
 
818
+ var maxDcCount = 0;
819
+ var maxEcCount = 0;
820
 
821
+ var dcdata = new Array(rsBlocks.length);
822
+ var ecdata = new Array(rsBlocks.length);
 
 
 
823
 
824
+ for (var r = 0; r < rsBlocks.length; r += 1) {
 
 
 
825
 
826
+ var dcCount = rsBlocks[r].dataCount;
827
+ var ecCount = rsBlocks[r].totalCount - dcCount;
828
+
829
+ maxDcCount = Math.max(maxDcCount, dcCount);
830
+ maxEcCount = Math.max(maxEcCount, ecCount);
 
831
 
832
+ dcdata[r] = new Array(dcCount);
833
+
834
+ for (var i = 0; i < dcdata[r].length; i += 1) {
835
+ dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
836
  }
837
+ offset += dcCount;
838
 
839
+ var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
840
+ var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
841
+
842
+ var modPoly = rawPoly.mod(rsPoly);
843
+ ecdata[r] = new Array(rsPoly.getLength() - 1);
844
+ for (var i = 0; i < ecdata[r].length; i += 1) {
845
+ var modIndex = i + modPoly.getLength() - ecdata[r].length;
846
+ ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;
 
 
 
 
847
  }
848
+ }
849
 
850
+ var totalCodeCount = 0;
851
+ for (var i = 0; i < rsBlocks.length; i += 1) {
852
+ totalCodeCount += rsBlocks[i].totalCount;
853
+ }
854
 
855
+ var data = new Array(totalCodeCount);
856
+ var index = 0;
857
+
858
+ for (var i = 0; i < maxDcCount; i += 1) {
859
+ for (var r = 0; r < rsBlocks.length; r += 1) {
860
+ if (i < dcdata[r].length) {
861
+ data[index] = dcdata[r][i];
862
+ index += 1;
863
+ }
864
  }
865
+ }
866
 
867
+ for (var i = 0; i < maxEcCount; i += 1) {
868
+ for (var r = 0; r < rsBlocks.length; r += 1) {
869
+ if (i < ecdata[r].length) {
870
+ data[index] = ecdata[r][i];
871
+ index += 1;
872
+ }
873
+ }
874
+ }
875
 
876
+ return data;
877
+ };
878
 
879
+ var createData = function(typeNumber, errorCorrectionLevel, dataList) {
 
 
 
 
880
 
881
+ var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel);
 
 
882
 
883
+ var buffer = qrBitBuffer();
 
884
 
885
+ for (var i = 0; i < dataList.length; i += 1) {
886
+ var data = dataList[i];
887
+ buffer.put(data.getMode(), 4);
888
+ buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
889
+ data.write(buffer);
890
+ }
891
 
892
+ // calc num max data.
893
+ var totalDataCount = 0;
894
+ for (var i = 0; i < rsBlocks.length; i += 1) {
895
+ totalDataCount += rsBlocks[i].dataCount;
896
+ }
897
 
898
+ if (buffer.getLengthInBits() > totalDataCount * 8) {
899
+ throw 'code length overflow. ('
900
+ + buffer.getLengthInBits()
901
+ + '>'
902
+ + totalDataCount * 8
903
+ + ')';
904
+ }
905
 
906
+ // end code
907
+ if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
908
+ buffer.put(0, 4);
909
+ }
910
 
911
+ // padding
912
+ while (buffer.getLengthInBits() % 8 != 0) {
913
+ buffer.putBit(false);
914
+ }
915
 
916
+ // padding
917
+ while (true) {
918
 
919
+ if (buffer.getLengthInBits() >= totalDataCount * 8) {
920
+ break;
921
+ }
922
+ buffer.put(PAD0, 8);
923
 
924
+ if (buffer.getLengthInBits() >= totalDataCount * 8) {
925
+ break;
926
+ }
927
+ buffer.put(PAD1, 8);
928
+ }
 
 
929
 
930
+ return createBytes(buffer, rsBlocks);
931
+ };
 
932
 
933
+ _this.addData = function(data, mode) {
934
+
935
+ mode = mode || 'Byte';
936
+
937
+ var newData = null;
938
+
939
+ switch(mode) {
940
+ case 'Numeric' :
941
+ newData = qrNumber(data);
942
+ break;
943
+ case 'Alphanumeric' :
944
+ newData = qrAlphaNum(data);
945
+ break;
946
+ case 'Byte' :
947
+ newData = qr8BitByte(data);
948
+ break;
949
+ case 'Kanji' :
950
+ newData = qrKanji(data);
951
+ break;
952
+ default :
953
+ throw 'mode:' + mode;
954
+ }
955
 
956
+ _dataList.push(newData);
957
+ _dataCache = null;
958
  };
959
 
960
+ _this.isDark = function(row, col) {
961
+ if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
962
+ throw row + ',' + col;
963
+ }
964
+ return _modules[row][col];
965
+ };
966
 
967
+ _this.getModuleCount = function() {
968
+ return _moduleCount;
 
 
 
 
 
969
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
970
 
971
+ _this.make = function() {
972
+ if (_typeNumber < 1) {
973
+ var typeNumber = 1;
974
+
975
+ for (; typeNumber < 40; typeNumber++) {
976
+ var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel);
977
+ var buffer = qrBitBuffer();
978
+
979
+ for (var i = 0; i < _dataList.length; i++) {
980
+ var data = _dataList[i];
981
+ buffer.put(data.getMode(), 4);
982
+ buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
983
+ data.write(buffer);
984
  }
985
 
986
+ var totalDataCount = 0;
987
+ for (var i = 0; i < rsBlocks.length; i++) {
988
+ totalDataCount += rsBlocks[i].dataCount;
989
+ }
990
 
991
+ if (buffer.getLengthInBits() <= totalDataCount * 8) {
992
+ break;
993
+ }
994
+ }
995
 
996
+ _typeNumber = typeNumber;
997
+ }
998
 
999
+ makeImpl(false, getBestMaskPattern() );
1000
+ };
1001
 
1002
+ _this.createTableTag = function(cellSize, margin) {
1003
 
1004
+ cellSize = cellSize || 2;
1005
+ margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
1006
 
1007
+ var qrHtml = '';
 
 
 
 
 
 
 
 
 
1008
 
1009
+ qrHtml += '<table style="';
1010
+ qrHtml += ' border-width: 0px; border-style: none;';
1011
+ qrHtml += ' border-collapse: collapse;';
1012
+ qrHtml += ' padding: 0px; margin: ' + margin + 'px;';
1013
+ qrHtml += '">';
1014
+ qrHtml += '<tbody>';
1015
 
1016
+ for (var r = 0; r < _this.getModuleCount(); r += 1) {
 
1017
 
1018
+ qrHtml += '<tr>';
1019
 
1020
+ for (var c = 0; c < _this.getModuleCount(); c += 1) {
1021
+ qrHtml += '<td style="';
1022
+ qrHtml += ' border-width: 0px; border-style: none;';
1023
+ qrHtml += ' border-collapse: collapse;';
1024
+ qrHtml += ' padding: 0px; margin: 0px;';
1025
+ qrHtml += ' width: ' + cellSize + 'px;';
1026
+ qrHtml += ' height: ' + cellSize + 'px;';
1027
+ qrHtml += ' background-color: ';
1028
+ qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';
1029
+ qrHtml += ';';
1030
+ qrHtml += '"/>';
1031
+ }
1032
 
1033
+ qrHtml += '</tr>';
1034
+ }
1035
 
1036
+ qrHtml += '</tbody>';
1037
+ qrHtml += '</table>';
 
 
 
1038
 
1039
+ return qrHtml;
1040
+ };
1041
 
1042
+ _this.createSvgTag = function(cellSize, margin) {
1043
 
1044
+ var opts = {};
1045
+ if (typeof arguments[0] == 'object') {
1046
+ // Called by options.
1047
+ opts = arguments[0];
1048
+ // overwrite cellSize and margin.
1049
+ cellSize = opts.cellSize;
1050
+ margin = opts.margin;
1051
+ }
1052
 
1053
+ cellSize = cellSize || 2;
1054
+ margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
1055
+ var size = _this.getModuleCount() * cellSize + margin * 2;
1056
+ var c, mc, r, mr, qrSvg='', rect;
 
 
 
1057
 
1058
+ rect = 'l' + cellSize + ',0 0,' + cellSize +
1059
+ ' -' + cellSize + ',0 0,-' + cellSize + 'z ';
1060
 
1061
+ qrSvg += '<svg version="1.1" xmlns="http://www.w3.org/2000/svg"';
1062
+ qrSvg += !opts.scalable ? ' width="' + size + 'px" height="' + size + 'px"' : '';
1063
+ qrSvg += ' viewBox="0 0 ' + size + ' ' + size + '" ';
1064
+ qrSvg += ' preserveAspectRatio="xMinYMin meet">';
1065
+ qrSvg += '<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>';
1066
+ qrSvg += '<path d="';
1067
 
1068
+ for (r = 0; r < _this.getModuleCount(); r += 1) {
1069
+ mr = r * cellSize + margin;
1070
+ for (c = 0; c < _this.getModuleCount(); c += 1) {
1071
+ if (_this.isDark(r, c) ) {
1072
+ mc = c*cellSize+margin;
1073
+ qrSvg += 'M' + mc + ',' + mr + rect;
1074
+ }
1075
+ }
1076
+ }
1077
 
1078
+ qrSvg += '" stroke="transparent" fill="black"/>';
1079
+ qrSvg += '</svg>';
1080
 
1081
+ return qrSvg;
1082
+ };
1083
 
1084
+ _this.createDataURL = function(cellSize, margin) {
 
 
1085
 
1086
+ cellSize = cellSize || 2;
1087
+ margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
1088
 
1089
+ var size = _this.getModuleCount() * cellSize + margin * 2;
1090
+ var min = margin;
1091
+ var max = size - margin;
1092
 
1093
+ return createDataURL(size, size, function(x, y) {
1094
+ if (min <= x && x < max && min <= y && y < max) {
1095
+ var c = Math.floor( (x - min) / cellSize);
1096
+ var r = Math.floor( (y - min) / cellSize);
1097
+ return _this.isDark(r, c)? 0 : 1;
1098
+ } else {
1099
+ return 1;
1100
+ }
1101
+ } );
1102
+ };
 
1103
 
1104
+ _this.createImgTag = function(cellSize, margin, alt) {
1105
+
1106
+ cellSize = cellSize || 2;
1107
+ margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
1108
+
1109
+ var size = _this.getModuleCount() * cellSize + margin * 2;
1110
+
1111
+ var img = '';
1112
+ img += '<img';
1113
+ img += '\u0020src="';
1114
+ img += _this.createDataURL(cellSize, margin);
1115
+ img += '"';
1116
+ img += '\u0020width="';
1117
+ img += size;
1118
+ img += '"';
1119
+ img += '\u0020height="';
1120
+ img += size;
1121
+ img += '"';
1122
+ if (alt) {
1123
+ img += '\u0020alt="';
1124
+ img += alt;
1125
+ img += '"';
1126
+ }
1127
+ img += '/>';
1128
 
1129
+ return img;
1130
+ };
1131
 
1132
+ var _createHalfASCII = function(margin) {
1133
+ var cellSize = 1;
1134
+ margin = (typeof margin == 'undefined')? cellSize * 2 : margin;
 
1135
 
1136
+ var size = _this.getModuleCount() * cellSize + margin * 2;
1137
+ var min = margin;
1138
+ var max = size - margin;
 
 
1139
 
1140
+ var y, x, r1, r2, p;
1141
 
1142
+ var blocks = {
1143
+ '██': '█',
1144
+ '█ ': '▀',
1145
+ ' █': '▄',
1146
+ ' ': ' '
1147
+ };
1148
 
1149
+ var blocksLastLineNoMargin = {
1150
+ '██': '▀',
1151
+ '█ ': '▀',
1152
+ ' █': ' ',
1153
+ ' ': ' '
1154
+ };
1155
 
1156
+ var ascii = '';
1157
+ for (y = 0; y < size; y += 2) {
1158
+ r1 = Math.floor((y - min) / cellSize);
1159
+ r2 = Math.floor((y + 1 - min) / cellSize);
1160
+ for (x = 0; x < size; x += 1) {
1161
+ p = '█';
1162
 
1163
+ if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) / cellSize))) {
1164
+ p = ' ';
 
 
 
 
 
1165
  }
1166
 
1167
+ if (min <= x && x < max && min <= y+1 && y+1 < max && _this.isDark(r2, Math.floor((x - min) / cellSize))) {
1168
+ p += ' ';
1169
+ }
1170
+ else {
1171
+ p += '█';
1172
+ }
1173
 
1174
+ // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.
1175
+ ascii += (margin < 1 && y+1 >= max) ? blocksLastLineNoMargin[p] : blocks[p];
1176
+ }
1177
 
1178
+ ascii += '\n';
1179
+ }
 
 
 
 
 
 
1180
 
1181
+ if (size % 2 && margin > 0) {
1182
+ return ascii.substring(0, ascii.length - size - 1) + Array(size+1).join('▀');
1183
+ }
1184
 
1185
+ return ascii.substring(0, ascii.length-1);
1186
+ };
1187
 
1188
+ _this.createASCII = function(cellSize, margin) {
1189
+ cellSize = cellSize || 1;
 
 
 
1190
 
1191
+ if (cellSize < 2) {
1192
+ return _createHalfASCII(margin);
1193
+ }
1194
 
1195
+ cellSize -= 1;
1196
+ margin = (typeof margin == 'undefined')? cellSize * 2 : margin;
1197
 
1198
+ var size = _this.getModuleCount() * cellSize + margin * 2;
1199
+ var min = margin;
1200
+ var max = size - margin;
1201
 
1202
+ var y, x, r, p;
1203
 
1204
+ var white = Array(cellSize+1).join('██');
1205
+ var black = Array(cellSize+1).join(' ');
1206
 
1207
+ var ascii = '';
1208
+ var line = '';
1209
+ for (y = 0; y < size; y += 1) {
1210
+ r = Math.floor( (y - min) / cellSize);
1211
+ line = '';
1212
+ for (x = 0; x < size; x += 1) {
1213
+ p = 1;
1214
 
1215
+ if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) / cellSize))) {
1216
+ p = 0;
1217
+ }
1218
 
1219
+ // Output 2 characters per pixel, to create full square. 1 character per pixels gives only half width of square.
1220
+ line += p ? white : black;
1221
+ }
1222
 
1223
+ for (r = 0; r < cellSize; r += 1) {
1224
+ ascii += line + '\n';
1225
+ }
1226
+ }
1227
 
1228
+ return ascii.substring(0, ascii.length-1);
1229
+ };
1230
 
1231
+ _this.renderTo2dContext = function(context, cellSize) {
1232
+ cellSize = cellSize || 2;
1233
+ var length = _this.getModuleCount();
1234
+ for (var row = 0; row < length; row++) {
1235
+ for (var col = 0; col < length; col++) {
1236
+ context.fillStyle = _this.isDark(row, col) ? 'black' : 'white';
1237
+ context.fillRect(row * cellSize, col * cellSize, cellSize, cellSize);
1238
+ }
1239
+ }
1240
+ }
1241
 
1242
+ return _this;
1243
+ };
1244
 
1245
+ //---------------------------------------------------------------------
1246
+ // qrcode.stringToBytes
1247
+ //---------------------------------------------------------------------
 
 
 
 
 
1248
 
1249
+ qrcode.stringToBytesFuncs = {
1250
+ 'default' : function(s) {
1251
+ var bytes = [];
1252
+ for (var i = 0; i < s.length; i += 1) {
1253
+ var c = s.charCodeAt(i);
1254
+ bytes.push(c & 0xff);
1255
+ }
1256
+ return bytes;
1257
+ }
1258
+ };
1259
 
1260
+ qrcode.stringToBytes = qrcode.stringToBytesFuncs['default'];
1261
 
1262
+ //---------------------------------------------------------------------
1263
+ // qrcode.createStringToBytes
1264
+ //---------------------------------------------------------------------
1265
 
1266
+ /**
1267
+ * @param unicodeData base64 string of byte array.
1268
+ * [16bit Unicode],[16bit Bytes], ...
1269
+ * @param numChars
1270
+ */
1271
+ qrcode.createStringToBytes = function(unicodeData, numChars) {
1272
 
1273
+ // create conversion map.
1274
 
1275
+ var unicodeMap = function() {
 
1276
 
1277
+ var bin = base64DecodeInputStream(unicodeData);
1278
+ var read = function() {
1279
+ var b = bin.read();
1280
+ if (b == -1) throw 'eof';
1281
+ return b;
1282
+ };
1283
 
1284
+ var count = 0;
1285
+ var unicodeMap = {};
1286
+ while (true) {
1287
+ var b0 = bin.read();
1288
+ if (b0 == -1) break;
1289
+ var b1 = read();
1290
+ var b2 = read();
1291
+ var b3 = read();
1292
+ var k = String.fromCharCode( (b0 << 8) | b1);
1293
+ var v = (b2 << 8) | b3;
1294
+ unicodeMap[k] = v;
1295
+ count += 1;
1296
+ }
1297
+ if (count != numChars) {
1298
+ throw count + ' != ' + numChars;
1299
+ }
1300
 
1301
+ return unicodeMap;
1302
+ }();
 
 
1303
 
1304
+ var unknownChar = '?'.charCodeAt(0);
 
1305
 
1306
+ return function(s) {
1307
+ var bytes = [];
1308
+ for (var i = 0; i < s.length; i += 1) {
1309
+ var c = s.charCodeAt(i);
1310
+ if (c < 128) {
1311
+ bytes.push(c);
1312
+ } else {
1313
+ var b = unicodeMap[s.charAt(i)];
1314
+ if (typeof b == 'number') {
1315
+ if ( (b & 0xff) == b) {
1316
+ // 1byte
1317
+ bytes.push(b);
1318
+ } else {
1319
+ // 2bytes
1320
+ bytes.push(b >>> 8);
1321
+ bytes.push(b & 0xff);
1322
  }
1323
+ } else {
1324
+ bytes.push(unknownChar);
1325
  }
1326
+ }
1327
+ }
1328
+ return bytes;
1329
+ };
1330
+ };
1331
+
1332
+ //---------------------------------------------------------------------
1333
+ // QRMode
1334
+ //---------------------------------------------------------------------
1335
+
1336
+ var QRMode = {
1337
+ MODE_NUMBER : 1 << 0,
1338
+ MODE_ALPHA_NUM : 1 << 1,
1339
+ MODE_8BIT_BYTE : 1 << 2,
1340
+ MODE_KANJI : 1 << 3
1341
+ };
1342
+
1343
+ //---------------------------------------------------------------------
1344
+ // QRErrorCorrectionLevel
1345
+ //---------------------------------------------------------------------
1346
+
1347
+ var QRErrorCorrectionLevel = {
1348
+ L : 1,
1349
+ M : 0,
1350
+ Q : 3,
1351
+ H : 2
1352
+ };
1353
+
1354
+ //---------------------------------------------------------------------
1355
+ // QRMaskPattern
1356
+ //---------------------------------------------------------------------
1357
+
1358
+ var QRMaskPattern = {
1359
+ PATTERN000 : 0,
1360
+ PATTERN001 : 1,
1361
+ PATTERN010 : 2,
1362
+ PATTERN011 : 3,
1363
+ PATTERN100 : 4,
1364
+ PATTERN101 : 5,
1365
+ PATTERN110 : 6,
1366
+ PATTERN111 : 7
1367
+ };
1368
+
1369
+ //---------------------------------------------------------------------
1370
+ // QRUtil
1371
+ //---------------------------------------------------------------------
1372
+
1373
+ var QRUtil = function() {
1374
+
1375
+ var PATTERN_POSITION_TABLE = [
1376
+ [],
1377
+ [6, 18],
1378
+ [6, 22],
1379
+ [6, 26],
1380
+ [6, 30],
1381
+ [6, 34],
1382
+ [6, 22, 38],
1383
+ [6, 24, 42],
1384
+ [6, 26, 46],
1385
+ [6, 28, 50],
1386
+ [6, 30, 54],
1387
+ [6, 32, 58],
1388
+ [6, 34, 62],
1389
+ [6, 26, 46, 66],
1390
+ [6, 26, 48, 70],
1391
+ [6, 26, 50, 74],
1392
+ [6, 30, 54, 78],
1393
+ [6, 30, 56, 82],
1394
+ [6, 30, 58, 86],
1395
+ [6, 34, 62, 90],
1396
+ [6, 28, 50, 72, 94],
1397
+ [6, 26, 50, 74, 98],
1398
+ [6, 30, 54, 78, 102],
1399
+ [6, 28, 54, 80, 106],
1400
+ [6, 32, 58, 84, 110],
1401
+ [6, 30, 58, 86, 114],
1402
+ [6, 34, 62, 90, 118],
1403
+ [6, 26, 50, 74, 98, 122],
1404
+ [6, 30, 54, 78, 102, 126],
1405
+ [6, 26, 52, 78, 104, 130],
1406
+ [6, 30, 56, 82, 108, 134],
1407
+ [6, 34, 60, 86, 112, 138],
1408
+ [6, 30, 58, 86, 114, 142],
1409
+ [6, 34, 62, 90, 118, 146],
1410
+ [6, 30, 54, 78, 102, 126, 150],
1411
+ [6, 24, 50, 76, 102, 128, 154],
1412
+ [6, 28, 54, 80, 106, 132, 158],
1413
+ [6, 32, 58, 84, 110, 136, 162],
1414
+ [6, 26, 54, 82, 110, 138, 166],
1415
+ [6, 30, 58, 86, 114, 142, 170]
1416
+ ];
1417
+ var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
1418
+ var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
1419
+ var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
1420
+
1421
+ var _this = {};
1422
+
1423
+ var getBCHDigit = function(data) {
1424
+ var digit = 0;
1425
+ while (data != 0) {
1426
+ digit += 1;
1427
+ data >>>= 1;
1428
+ }
1429
+ return digit;
1430
+ };
1431
 
1432
+ _this.getBCHTypeInfo = function(data) {
1433
+ var d = data << 10;
1434
+ while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {
1435
+ d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );
1436
+ }
1437
+ return ( (data << 10) | d) ^ G15_MASK;
1438
+ };
1439
 
1440
+ _this.getBCHTypeNumber = function(data) {
1441
+ var d = data << 12;
1442
+ while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {
1443
+ d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );
1444
+ }
1445
+ return (data << 12) | d;
1446
+ };
1447
 
1448
+ _this.getPatternPosition = function(typeNumber) {
1449
+ return PATTERN_POSITION_TABLE[typeNumber - 1];
1450
+ };
 
 
 
 
 
1451
 
1452
+ _this.getMaskFunction = function(maskPattern) {
1453
+
1454
+ switch (maskPattern) {
1455
+
1456
+ case QRMaskPattern.PATTERN000 :
1457
+ return function(i, j) { return (i + j) % 2 == 0; };
1458
+ case QRMaskPattern.PATTERN001 :
1459
+ return function(i, j) { return i % 2 == 0; };
1460
+ case QRMaskPattern.PATTERN010 :
1461
+ return function(i, j) { return j % 3 == 0; };
1462
+ case QRMaskPattern.PATTERN011 :
1463
+ return function(i, j) { return (i + j) % 3 == 0; };
1464
+ case QRMaskPattern.PATTERN100 :
1465
+ return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };
1466
+ case QRMaskPattern.PATTERN101 :
1467
+ return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };
1468
+ case QRMaskPattern.PATTERN110 :
1469
+ return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };
1470
+ case QRMaskPattern.PATTERN111 :
1471
+ return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };
1472
+
1473
+ default :
1474
+ throw 'bad maskPattern:' + maskPattern;
1475
+ }
1476
+ };
1477
 
1478
+ _this.getErrorCorrectPolynomial = function(errorCorrectLength) {
1479
+ var a = qrPolynomial([1], 0);
1480
+ for (var i = 0; i < errorCorrectLength; i += 1) {
1481
+ a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );
1482
+ }
1483
+ return a;
1484
+ };
1485
 
1486
+ _this.getLengthInBits = function(mode, type) {
1487
 
1488
+ if (1 <= type && type < 10) {
1489
 
1490
+ // 1 - 9
1491
 
1492
+ switch(mode) {
1493
+ case QRMode.MODE_NUMBER : return 10;
1494
+ case QRMode.MODE_ALPHA_NUM : return 9;
1495
+ case QRMode.MODE_8BIT_BYTE : return 8;
1496
+ case QRMode.MODE_KANJI : return 8;
1497
+ default :
1498
+ throw 'mode:' + mode;
1499
+ }
1500
 
1501
+ } else if (type < 27) {
 
 
 
 
1502
 
1503
+ // 10 - 26
 
 
 
 
 
 
1504
 
1505
+ switch(mode) {
1506
+ case QRMode.MODE_NUMBER : return 12;
1507
+ case QRMode.MODE_ALPHA_NUM : return 11;
1508
+ case QRMode.MODE_8BIT_BYTE : return 16;
1509
+ case QRMode.MODE_KANJI : return 10;
1510
+ default :
1511
+ throw 'mode:' + mode;
1512
+ }
1513
 
1514
+ } else if (type < 41) {
 
 
 
1515
 
1516
+ // 27 - 40
 
1517
 
1518
+ switch(mode) {
1519
+ case QRMode.MODE_NUMBER : return 14;
1520
+ case QRMode.MODE_ALPHA_NUM : return 13;
1521
+ case QRMode.MODE_8BIT_BYTE : return 16;
1522
+ case QRMode.MODE_KANJI : return 12;
1523
+ default :
1524
+ throw 'mode:' + mode;
1525
+ }
1526
 
1527
+ } else {
1528
+ throw 'type:' + type;
1529
+ }
1530
+ };
 
1531
 
1532
+ _this.getLostPoint = function(qrcode) {
 
1533
 
1534
+ var moduleCount = qrcode.getModuleCount();
 
 
 
 
1535
 
1536
+ var lostPoint = 0;
 
 
 
 
 
1537
 
1538
+ // LEVEL1
 
 
1539
 
1540
+ for (var row = 0; row < moduleCount; row += 1) {
1541
+ for (var col = 0; col < moduleCount; col += 1) {
 
1542
 
1543
+ var sameCount = 0;
1544
+ var dark = qrcode.isDark(row, col);
1545
 
1546
+ for (var r = -1; r <= 1; r += 1) {
 
1547
 
1548
+ if (row + r < 0 || moduleCount <= row + r) {
1549
+ continue;
1550
+ }
1551
 
1552
+ for (var c = -1; c <= 1; c += 1) {
1553
+
1554
+ if (col + c < 0 || moduleCount <= col + c) {
1555
+ continue;
1556
+ }
1557
+
1558
+ if (r == 0 && c == 0) {
1559
+ continue;
1560
+ }
1561
+
1562
+ if (dark == qrcode.isDark(row + r, col + c) ) {
1563
+ sameCount += 1;
1564
+ }
 
 
 
 
 
 
 
 
 
1565
  }
1566
+ }
1567
+
1568
+ if (sameCount > 5) {
1569
+ lostPoint += (3 + sameCount - 5);
1570
+ }
1571
+ }
1572
+ };
1573
+
1574
+ // LEVEL2
1575
+
1576
+ for (var row = 0; row < moduleCount - 1; row += 1) {
1577
+ for (var col = 0; col < moduleCount - 1; col += 1) {
1578
+ var count = 0;
1579
+ if (qrcode.isDark(row, col) ) count += 1;
1580
+ if (qrcode.isDark(row + 1, col) ) count += 1;
1581
+ if (qrcode.isDark(row, col + 1) ) count += 1;
1582
+ if (qrcode.isDark(row + 1, col + 1) ) count += 1;
1583
+ if (count == 0 || count == 4) {
1584
+ lostPoint += 3;
1585
+ }
1586
+ }
1587
+ }
1588
 
1589
+ // LEVEL3
1590
+
1591
+ for (var row = 0; row < moduleCount; row += 1) {
1592
+ for (var col = 0; col < moduleCount - 6; col += 1) {
1593
+ if (qrcode.isDark(row, col)
1594
+ && !qrcode.isDark(row, col + 1)
1595
+ && qrcode.isDark(row, col + 2)
1596
+ && qrcode.isDark(row, col + 3)
1597
+ && qrcode.isDark(row, col + 4)
1598
+ && !qrcode.isDark(row, col + 5)
1599
+ && qrcode.isDark(row, col + 6) ) {
1600
+ lostPoint += 40;
1601
  }
1602
+ }
1603
+ }
1604
 
1605
+ for (var col = 0; col < moduleCount; col += 1) {
1606
+ for (var row = 0; row < moduleCount - 6; row += 1) {
1607
+ if (qrcode.isDark(row, col)
1608
+ && !qrcode.isDark(row + 1, col)
1609
+ && qrcode.isDark(row + 2, col)
1610
+ && qrcode.isDark(row + 3, col)
1611
+ && qrcode.isDark(row + 4, col)
1612
+ && !qrcode.isDark(row + 5, col)
1613
+ && qrcode.isDark(row + 6, col) ) {
1614
+ lostPoint += 40;
1615
+ }
1616
+ }
1617
+ }
1618
 
1619
+ // LEVEL4
 
1620
 
1621
+ var darkCount = 0;
1622
 
1623
+ for (var col = 0; col < moduleCount; col += 1) {
1624
+ for (var row = 0; row < moduleCount; row += 1) {
1625
+ if (qrcode.isDark(row, col) ) {
1626
+ darkCount += 1;
1627
+ }
1628
+ }
1629
+ }
1630
 
1631
+ var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
1632
+ lostPoint += ratio * 10;
 
1633
 
1634
+ return lostPoint;
1635
+ };
 
 
 
 
 
 
 
 
1636
 
1637
+ return _this;
1638
+ }();
1639
 
1640
+ //---------------------------------------------------------------------
1641
+ // QRMath
1642
+ //---------------------------------------------------------------------
1643
 
1644
+ var QRMath = function() {
 
 
 
 
 
 
 
1645
 
1646
+ var EXP_TABLE = new Array(256);
1647
+ var LOG_TABLE = new Array(256);
 
1648
 
1649
+ // initialize tables
1650
+ for (var i = 0; i < 8; i += 1) {
1651
+ EXP_TABLE[i] = 1 << i;
1652
+ }
1653
+ for (var i = 8; i < 256; i += 1) {
1654
+ EXP_TABLE[i] = EXP_TABLE[i - 4]
1655
+ ^ EXP_TABLE[i - 5]
1656
+ ^ EXP_TABLE[i - 6]
1657
+ ^ EXP_TABLE[i - 8];
1658
+ }
1659
+ for (var i = 0; i < 255; i += 1) {
1660
+ LOG_TABLE[EXP_TABLE[i] ] = i;
1661
+ }
1662
 
1663
+ var _this = {};
1664
 
1665
+ _this.glog = function(n) {
1666
 
1667
+ if (n < 1) {
1668
+ throw 'glog(' + n + ')';
1669
+ }
 
 
 
1670
 
1671
+ return LOG_TABLE[n];
1672
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1673
 
1674
+ _this.gexp = function(n) {
 
1675
 
1676
+ while (n < 0) {
1677
+ n += 255;
1678
+ }
1679
 
1680
+ while (n >= 256) {
1681
+ n -= 255;
1682
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1683
 
1684
+ return EXP_TABLE[n];
1685
+ };
 
1686
 
1687
+ return _this;
1688
+ }();
 
 
 
 
1689
 
1690
+ //---------------------------------------------------------------------
1691
+ // qrPolynomial
1692
+ //---------------------------------------------------------------------
1693
 
1694
+ function qrPolynomial(num, shift) {
 
 
 
 
 
1695
 
1696
+ if (typeof num.length == 'undefined') {
1697
+ throw num.length + '/' + shift;
1698
+ }
 
 
 
 
 
 
 
 
 
 
 
1699
 
1700
+ var _num = function() {
1701
+ var offset = 0;
1702
+ while (offset < num.length && num[offset] == 0) {
1703
+ offset += 1;
1704
+ }
1705
+ var _num = new Array(num.length - offset + shift);
1706
+ for (var i = 0; i < num.length - offset; i += 1) {
1707
+ _num[i] = num[i + offset];
1708
+ }
1709
+ return _num;
1710
+ }();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1711
 
1712
+ var _this = {};
 
 
 
 
 
 
1713
 
1714
+ _this.getAt = function(index) {
1715
+ return _num[index];
1716
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1717
 
1718
+ _this.getLength = function() {
1719
+ return _num.length;
1720
+ };
 
 
 
 
1721
 
1722
+ _this.multiply = function(e) {
1723
 
1724
+ var num = new Array(_this.getLength() + e.getLength() - 1);
1725
 
1726
+ for (var i = 0; i < _this.getLength(); i += 1) {
1727
+ for (var j = 0; j < e.getLength(); j += 1) {
1728
+ num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );
1729
+ }
1730
+ }
1731
 
1732
+ return qrPolynomial(num, 0);
1733
+ };
 
 
 
 
 
 
1734
 
1735
+ _this.mod = function(e) {
1736
 
1737
+ if (_this.getLength() - e.getLength() < 0) {
1738
+ return _this;
1739
+ }
1740
 
1741
+ var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );
 
 
 
 
 
 
 
1742
 
1743
+ var num = new Array(_this.getLength() );
1744
+ for (var i = 0; i < _this.getLength(); i += 1) {
1745
+ num[i] = _this.getAt(i);
1746
+ }
1747
 
1748
+ for (var i = 0; i < e.getLength(); i += 1) {
1749
+ num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);
1750
+ }
1751
 
1752
+ // recursive call
1753
+ return qrPolynomial(num, 0).mod(e);
1754
+ };
 
 
 
 
 
1755
 
1756
+ return _this;
1757
+ };
1758
+
1759
+ //---------------------------------------------------------------------
1760
+ // QRRSBlock
1761
+ //---------------------------------------------------------------------
1762
+
1763
+ var QRRSBlock = function() {
1764
+
1765
+ var RS_BLOCK_TABLE = [
1766
+
1767
+ // L
1768
+ // M
1769
+ // Q
1770
+ // H
1771
+
1772
+ // 1
1773
+ [1, 26, 19],
1774
+ [1, 26, 16],
1775
+ [1, 26, 13],
1776
+ [1, 26, 9],
1777
+
1778
+ // 2
1779
+ [1, 44, 34],
1780
+ [1, 44, 28],
1781
+ [1, 44, 22],
1782
+ [1, 44, 16],
1783
+
1784
+ // 3
1785
+ [1, 70, 55],
1786
+ [1, 70, 44],
1787
+ [2, 35, 17],
1788
+ [2, 35, 13],
1789
+
1790
+ // 4
1791
+ [1, 100, 80],
1792
+ [2, 50, 32],
1793
+ [2, 50, 24],
1794
+ [4, 25, 9],
1795
+
1796
+ // 5
1797
+ [1, 134, 108],
1798
+ [2, 67, 43],
1799
+ [2, 33, 15, 2, 34, 16],
1800
+ [2, 33, 11, 2, 34, 12],
1801
+
1802
+ // 6
1803
+ [2, 86, 68],
1804
+ [4, 43, 27],
1805
+ [4, 43, 19],
1806
+ [4, 43, 15],
1807
+
1808
+ // 7
1809
+ [2, 98, 78],
1810
+ [4, 49, 31],
1811
+ [2, 32, 14, 4, 33, 15],
1812
+ [4, 39, 13, 1, 40, 14],
1813
+
1814
+ // 8
1815
+ [2, 121, 97],
1816
+ [2, 60, 38, 2, 61, 39],
1817
+ [4, 40, 18, 2, 41, 19],
1818
+ [4, 40, 14, 2, 41, 15],
1819
+
1820
+ // 9
1821
+ [2, 146, 116],
1822
+ [3, 58, 36, 2, 59, 37],
1823
+ [4, 36, 16, 4, 37, 17],
1824
+ [4, 36, 12, 4, 37, 13],
1825
+
1826
+ // 10
1827
+ [2, 86, 68, 2, 87, 69],
1828
+ [4, 69, 43, 1, 70, 44],
1829
+ [6, 43, 19, 2, 44, 20],
1830
+ [6, 43, 15, 2, 44, 16],
1831
+
1832
+ // 11
1833
+ [4, 101, 81],
1834
+ [1, 80, 50, 4, 81, 51],
1835
+ [4, 50, 22, 4, 51, 23],
1836
+ [3, 36, 12, 8, 37, 13],
1837
+
1838
+ // 12
1839
+ [2, 116, 92, 2, 117, 93],
1840
+ [6, 58, 36, 2, 59, 37],
1841
+ [4, 46, 20, 6, 47, 21],
1842
+ [7, 42, 14, 4, 43, 15],
1843
+
1844
+ // 13
1845
+ [4, 133, 107],
1846
+ [8, 59, 37, 1, 60, 38],
1847
+ [8, 44, 20, 4, 45, 21],
1848
+ [12, 33, 11, 4, 34, 12],
1849
+
1850
+ // 14
1851
+ [3, 145, 115, 1, 146, 116],
1852
+ [4, 64, 40, 5, 65, 41],
1853
+ [11, 36, 16, 5, 37, 17],
1854
+ [11, 36, 12, 5, 37, 13],
1855
+
1856
+ // 15
1857
+ [5, 109, 87, 1, 110, 88],
1858
+ [5, 65, 41, 5, 66, 42],
1859
+ [5, 54, 24, 7, 55, 25],
1860
+ [11, 36, 12, 7, 37, 13],
1861
+
1862
+ // 16
1863
+ [5, 122, 98, 1, 123, 99],
1864
+ [7, 73, 45, 3, 74, 46],
1865
+ [15, 43, 19, 2, 44, 20],
1866
+ [3, 45, 15, 13, 46, 16],
1867
+
1868
+ // 17
1869
+ [1, 135, 107, 5, 136, 108],
1870
+ [10, 74, 46, 1, 75, 47],
1871
+ [1, 50, 22, 15, 51, 23],
1872
+ [2, 42, 14, 17, 43, 15],
1873
+
1874
+ // 18
1875
+ [5, 150, 120, 1, 151, 121],
1876
+ [9, 69, 43, 4, 70, 44],
1877
+ [17, 50, 22, 1, 51, 23],
1878
+ [2, 42, 14, 19, 43, 15],
1879
+
1880
+ // 19
1881
+ [3, 141, 113, 4, 142, 114],
1882
+ [3, 70, 44, 11, 71, 45],
1883
+ [17, 47, 21, 4, 48, 22],
1884
+ [9, 39, 13, 16, 40, 14],
1885
+
1886
+ // 20
1887
+ [3, 135, 107, 5, 136, 108],
1888
+ [3, 67, 41, 13, 68, 42],
1889
+ [15, 54, 24, 5, 55, 25],
1890
+ [15, 43, 15, 10, 44, 16],
1891
+
1892
+ // 21
1893
+ [4, 144, 116, 4, 145, 117],
1894
+ [17, 68, 42],
1895
+ [17, 50, 22, 6, 51, 23],
1896
+ [19, 46, 16, 6, 47, 17],
1897
+
1898
+ // 22
1899
+ [2, 139, 111, 7, 140, 112],
1900
+ [17, 74, 46],
1901
+ [7, 54, 24, 16, 55, 25],
1902
+ [34, 37, 13],
1903
+
1904
+ // 23
1905
+ [4, 151, 121, 5, 152, 122],
1906
+ [4, 75, 47, 14, 76, 48],
1907
+ [11, 54, 24, 14, 55, 25],
1908
+ [16, 45, 15, 14, 46, 16],
1909
+
1910
+ // 24
1911
+ [6, 147, 117, 4, 148, 118],
1912
+ [6, 73, 45, 14, 74, 46],
1913
+ [11, 54, 24, 16, 55, 25],
1914
+ [30, 46, 16, 2, 47, 17],
1915
+
1916
+ // 25
1917
+ [8, 132, 106, 4, 133, 107],
1918
+ [8, 75, 47, 13, 76, 48],
1919
+ [7, 54, 24, 22, 55, 25],
1920
+ [22, 45, 15, 13, 46, 16],
1921
+
1922
+ // 26
1923
+ [10, 142, 114, 2, 143, 115],
1924
+ [19, 74, 46, 4, 75, 47],
1925
+ [28, 50, 22, 6, 51, 23],
1926
+ [33, 46, 16, 4, 47, 17],
1927
+
1928
+ // 27
1929
+ [8, 152, 122, 4, 153, 123],
1930
+ [22, 73, 45, 3, 74, 46],
1931
+ [8, 53, 23, 26, 54, 24],
1932
+ [12, 45, 15, 28, 46, 16],
1933
+
1934
+ // 28
1935
+ [3, 147, 117, 10, 148, 118],
1936
+ [3, 73, 45, 23, 74, 46],
1937
+ [4, 54, 24, 31, 55, 25],
1938
+ [11, 45, 15, 31, 46, 16],
1939
+
1940
+ // 29
1941
+ [7, 146, 116, 7, 147, 117],
1942
+ [21, 73, 45, 7, 74, 46],
1943
+ [1, 53, 23, 37, 54, 24],
1944
+ [19, 45, 15, 26, 46, 16],
1945
+
1946
+ // 30
1947
+ [5, 145, 115, 10, 146, 116],
1948
+ [19, 75, 47, 10, 76, 48],
1949
+ [15, 54, 24, 25, 55, 25],
1950
+ [23, 45, 15, 25, 46, 16],
1951
+
1952
+ // 31
1953
+ [13, 145, 115, 3, 146, 116],
1954
+ [2, 74, 46, 29, 75, 47],
1955
+ [42, 54, 24, 1, 55, 25],
1956
+ [23, 45, 15, 28, 46, 16],
1957
+
1958
+ // 32
1959
+ [17, 145, 115],
1960
+ [10, 74, 46, 23, 75, 47],
1961
+ [10, 54, 24, 35, 55, 25],
1962
+ [19, 45, 15, 35, 46, 16],
1963
+
1964
+ // 33
1965
+ [17, 145, 115, 1, 146, 116],
1966
+ [14, 74, 46, 21, 75, 47],
1967
+ [29, 54, 24, 19, 55, 25],
1968
+ [11, 45, 15, 46, 46, 16],
1969
+
1970
+ // 34
1971
+ [13, 145, 115, 6, 146, 116],
1972
+ [14, 74, 46, 23, 75, 47],
1973
+ [44, 54, 24, 7, 55, 25],
1974
+ [59, 46, 16, 1, 47, 17],
1975
+
1976
+ // 35
1977
+ [12, 151, 121, 7, 152, 122],
1978
+ [12, 75, 47, 26, 76, 48],
1979
+ [39, 54, 24, 14, 55, 25],
1980
+ [22, 45, 15, 41, 46, 16],
1981
+
1982
+ // 36
1983
+ [6, 151, 121, 14, 152, 122],
1984
+ [6, 75, 47, 34, 76, 48],
1985
+ [46, 54, 24, 10, 55, 25],
1986
+ [2, 45, 15, 64, 46, 16],
1987
+
1988
+ // 37
1989
+ [17, 152, 122, 4, 153, 123],
1990
+ [29, 74, 46, 14, 75, 47],
1991
+ [49, 54, 24, 10, 55, 25],
1992
+ [24, 45, 15, 46, 46, 16],
1993
+
1994
+ // 38
1995
+ [4, 152, 122, 18, 153, 123],
1996
+ [13, 74, 46, 32, 75, 47],
1997
+ [48, 54, 24, 14, 55, 25],
1998
+ [42, 45, 15, 32, 46, 16],
1999
+
2000
+ // 39
2001
+ [20, 147, 117, 4, 148, 118],
2002
+ [40, 75, 47, 7, 76, 48],
2003
+ [43, 54, 24, 22, 55, 25],
2004
+ [10, 45, 15, 67, 46, 16],
2005
+
2006
+ // 40
2007
+ [19, 148, 118, 6, 149, 119],
2008
+ [18, 75, 47, 31, 76, 48],
2009
+ [34, 54, 24, 34, 55, 25],
2010
+ [20, 45, 15, 61, 46, 16]
2011
+ ];
2012
+
2013
+ var qrRSBlock = function(totalCount, dataCount) {
2014
+ var _this = {};
2015
+ _this.totalCount = totalCount;
2016
+ _this.dataCount = dataCount;
2017
+ return _this;
2018
+ };
2019
 
2020
+ var _this = {};
2021
 
2022
+ var getRsBlockTable = function(typeNumber, errorCorrectionLevel) {
2023
 
2024
+ switch(errorCorrectionLevel) {
2025
+ case QRErrorCorrectionLevel.L :
2026
+ return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
2027
+ case QRErrorCorrectionLevel.M :
2028
+ return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
2029
+ case QRErrorCorrectionLevel.Q :
2030
+ return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
2031
+ case QRErrorCorrectionLevel.H :
2032
+ return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
2033
+ default :
2034
+ return undefined;
2035
+ }
2036
+ };
2037
 
2038
+ _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) {
2039
 
2040
+ var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel);
 
2041
 
2042
+ if (typeof rsBlock == 'undefined') {
2043
+ throw 'bad rs block @ typeNumber:' + typeNumber +
2044
+ '/errorCorrectionLevel:' + errorCorrectionLevel;
2045
+ }
2046
 
2047
+ var length = rsBlock.length / 3;
2048
 
2049
+ var list = [];
 
 
2050
 
2051
+ for (var i = 0; i < length; i += 1) {
2052
 
2053
+ var count = rsBlock[i * 3 + 0];
2054
+ var totalCount = rsBlock[i * 3 + 1];
2055
+ var dataCount = rsBlock[i * 3 + 2];
2056
 
2057
+ for (var j = 0; j < count; j += 1) {
2058
+ list.push(qrRSBlock(totalCount, dataCount) );
2059
+ }
2060
+ }
2061
 
2062
+ return list;
2063
+ };
 
 
 
2064
 
2065
+ return _this;
2066
+ }();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2067
 
2068
+ //---------------------------------------------------------------------
2069
+ // qrBitBuffer
2070
+ //---------------------------------------------------------------------
 
 
 
 
 
 
 
 
 
 
 
 
2071
 
2072
+ var qrBitBuffer = function() {
 
 
 
 
 
 
 
 
 
 
 
 
2073
 
2074
+ var _buffer = [];
2075
+ var _length = 0;
2076
 
2077
+ var _this = {};
2078
 
2079
+ _this.getBuffer = function() {
2080
+ return _buffer;
2081
+ };
 
 
 
 
2082
 
2083
+ _this.getAt = function(index) {
2084
+ var bufIndex = Math.floor(index / 8);
2085
+ return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
2086
+ };
2087
 
2088
+ _this.put = function(num, length) {
2089
+ for (var i = 0; i < length; i += 1) {
2090
+ _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
2091
+ }
2092
+ };
2093
 
2094
+ _this.getLengthInBits = function() {
2095
+ return _length;
2096
+ };
2097
 
2098
+ _this.putBit = function(bit) {
 
 
2099
 
2100
+ var bufIndex = Math.floor(_length / 8);
2101
+ if (_buffer.length <= bufIndex) {
2102
+ _buffer.push(0);
2103
+ }
2104
 
2105
+ if (bit) {
2106
+ _buffer[bufIndex] |= (0x80 >>> (_length % 8) );
2107
+ }
2108
 
2109
+ _length += 1;
2110
+ };
 
 
 
 
 
 
 
 
 
 
 
2111
 
2112
+ return _this;
2113
+ };
2114
 
2115
+ //---------------------------------------------------------------------
2116
+ // qrNumber
2117
+ //---------------------------------------------------------------------
2118
 
2119
+ var qrNumber = function(data) {
 
 
2120
 
2121
+ var _mode = QRMode.MODE_NUMBER;
2122
+ var _data = data;
2123
 
2124
+ var _this = {};
2125
 
2126
+ _this.getMode = function() {
2127
+ return _mode;
2128
+ };
2129
 
2130
+ _this.getLength = function(buffer) {
2131
+ return _data.length;
2132
+ };
2133
 
2134
+ _this.write = function(buffer) {
 
2135
 
2136
+ var data = _data;
 
2137
 
2138
+ var i = 0;
 
 
2139
 
2140
+ while (i + 2 < data.length) {
2141
+ buffer.put(strToNum(data.substring(i, i + 3) ), 10);
2142
+ i += 3;
2143
+ }
2144
 
2145
+ if (i < data.length) {
2146
+ if (data.length - i == 1) {
2147
+ buffer.put(strToNum(data.substring(i, i + 1) ), 4);
2148
+ } else if (data.length - i == 2) {
2149
+ buffer.put(strToNum(data.substring(i, i + 2) ), 7);
2150
  }
2151
+ }
2152
+ };
2153
 
2154
+ var strToNum = function(s) {
2155
+ var num = 0;
2156
+ for (var i = 0; i < s.length; i += 1) {
2157
+ num = num * 10 + chatToNum(s.charAt(i) );
2158
+ }
2159
+ return num;
2160
+ };
 
 
 
 
 
 
2161
 
2162
+ var chatToNum = function(c) {
2163
+ if ('0' <= c && c <= '9') {
2164
+ return c.charCodeAt(0) - '0'.charCodeAt(0);
2165
+ }
2166
+ throw 'illegal char :' + c;
2167
+ };
2168
 
2169
+ return _this;
2170
+ };
 
2171
 
2172
+ //---------------------------------------------------------------------
2173
+ // qrAlphaNum
2174
+ //---------------------------------------------------------------------
2175
 
2176
+ var qrAlphaNum = function(data) {
2177
 
2178
+ var _mode = QRMode.MODE_ALPHA_NUM;
2179
+ var _data = data;
 
 
 
2180
 
2181
+ var _this = {};
 
2182
 
2183
+ _this.getMode = function() {
2184
+ return _mode;
2185
+ };
2186
 
2187
+ _this.getLength = function(buffer) {
2188
+ return _data.length;
2189
+ };
2190
 
2191
+ _this.write = function(buffer) {
2192
 
2193
+ var s = _data;
 
 
 
2194
 
2195
+ var i = 0;
 
 
2196
 
2197
+ while (i + 1 < s.length) {
2198
+ buffer.put(
2199
+ getCode(s.charAt(i) ) * 45 +
2200
+ getCode(s.charAt(i + 1) ), 11);
2201
+ i += 2;
2202
+ }
2203
 
2204
+ if (i < s.length) {
2205
+ buffer.put(getCode(s.charAt(i) ), 6);
2206
+ }
2207
+ };
2208
 
2209
+ var getCode = function(c) {
2210
+
2211
+ if ('0' <= c && c <= '9') {
2212
+ return c.charCodeAt(0) - '0'.charCodeAt(0);
2213
+ } else if ('A' <= c && c <= 'Z') {
2214
+ return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10;
2215
+ } else {
2216
+ switch (c) {
2217
+ case ' ' : return 36;
2218
+ case '$' : return 37;
2219
+ case '%' : return 38;
2220
+ case '*' : return 39;
2221
+ case '+' : return 40;
2222
+ case '-' : return 41;
2223
+ case '.' : return 42;
2224
+ case '/' : return 43;
2225
+ case ':' : return 44;
2226
+ default :
2227
+ throw 'illegal char :' + c;
2228
+ }
2229
+ }
2230
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2231
 
2232
+ return _this;
2233
+ };
2234
 
2235
+ //---------------------------------------------------------------------
2236
+ // qr8BitByte
2237
+ //---------------------------------------------------------------------
2238
 
2239
+ var qr8BitByte = function(data) {
 
 
 
2240
 
2241
+ var _mode = QRMode.MODE_8BIT_BYTE;
2242
+ var _data = data;
2243
+ var _bytes = qrcode.stringToBytes(data);
2244
 
2245
+ var _this = {};
2246
 
2247
+ _this.getMode = function() {
2248
+ return _mode;
2249
+ };
2250
 
2251
+ _this.getLength = function(buffer) {
2252
+ return _bytes.length;
2253
+ };
2254
 
2255
+ _this.write = function(buffer) {
2256
+ for (var i = 0; i < _bytes.length; i += 1) {
2257
+ buffer.put(_bytes[i], 8);
2258
+ }
2259
+ };
2260
 
2261
+ return _this;
2262
+ };
2263
 
2264
+ //---------------------------------------------------------------------
2265
+ // qrKanji
2266
+ //---------------------------------------------------------------------
2267
 
2268
+ var qrKanji = function(data) {
 
 
2269
 
2270
+ var _mode = QRMode.MODE_KANJI;
2271
+ var _data = data;
2272
 
2273
+ var stringToBytes = qrcode.stringToBytesFuncs['SJIS'];
2274
+ if (!stringToBytes) {
2275
+ throw 'sjis not supported.';
2276
+ }
2277
+ !function(c, code) {
2278
+ // self test for sjis support.
2279
+ var test = stringToBytes(c);
2280
+ if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) {
2281
+ throw 'sjis not supported.';
2282
+ }
2283
+ }('\u53cb', 0x9746);
2284
 
2285
+ var _bytes = stringToBytes(data);
2286
 
2287
+ var _this = {};
 
 
2288
 
2289
+ _this.getMode = function() {
2290
+ return _mode;
2291
+ };
 
2292
 
2293
+ _this.getLength = function(buffer) {
2294
+ return ~~(_bytes.length / 2);
2295
+ };
 
 
2296
 
2297
+ _this.write = function(buffer) {
 
 
2298
 
2299
+ var data = _bytes;
2300
 
2301
+ var i = 0;
 
 
 
2302
 
2303
+ while (i + 1 < data.length) {
 
 
2304
 
2305
+ var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]);
 
2306
 
2307
+ if (0x8140 <= c && c <= 0x9FFC) {
2308
+ c -= 0x8140;
2309
+ } else if (0xE040 <= c && c <= 0xEBBF) {
2310
+ c -= 0xC140;
2311
+ } else {
2312
+ throw 'illegal char at ' + (i + 1) + '/' + c;
2313
+ }
2314
 
2315
+ c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff);
 
 
2316
 
2317
+ buffer.put(c, 13);
2318
 
2319
+ i += 2;
2320
+ }
 
2321
 
2322
+ if (i < data.length) {
2323
+ throw 'illegal char at ' + (i + 1);
2324
+ }
2325
+ };
2326
 
2327
+ return _this;
2328
+ };
 
2329
 
2330
+ //=====================================================================
2331
+ // GIF Support etc.
2332
+ //
2333
 
2334
+ //---------------------------------------------------------------------
2335
+ // byteArrayOutputStream
2336
+ //---------------------------------------------------------------------
 
 
2337
 
2338
+ var byteArrayOutputStream = function() {
 
2339
 
2340
+ var _bytes = [];
 
 
2341
 
2342
+ var _this = {};
 
 
2343
 
2344
+ _this.writeByte = function(b) {
2345
+ _bytes.push(b & 0xff);
2346
+ };
2347
 
2348
+ _this.writeShort = function(i) {
2349
+ _this.writeByte(i);
2350
+ _this.writeByte(i >>> 8);
2351
+ };
2352
 
2353
+ _this.writeBytes = function(b, off, len) {
2354
+ off = off || 0;
2355
+ len = len || b.length;
2356
+ for (var i = 0; i < len; i += 1) {
2357
+ _this.writeByte(b[i + off]);
2358
+ }
2359
+ };
2360
 
2361
+ _this.writeString = function(s) {
2362
+ for (var i = 0; i < s.length; i += 1) {
2363
+ _this.writeByte(s.charCodeAt(i) );
2364
+ }
2365
+ };
2366
 
2367
+ _this.toByteArray = function() {
2368
+ return _bytes;
2369
+ };
 
2370
 
2371
+ _this.toString = function() {
2372
+ var s = '';
2373
+ s += '[';
2374
+ for (var i = 0; i < _bytes.length; i += 1) {
2375
+ if (i > 0) {
2376
+ s += ',';
2377
+ }
2378
+ s += _bytes[i];
2379
+ }
2380
+ s += ']';
2381
+ return s;
2382
+ };
2383
 
2384
+ return _this;
2385
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2386
 
2387
+ //---------------------------------------------------------------------
2388
+ // base64EncodeOutputStream
2389
+ //---------------------------------------------------------------------
2390
 
2391
+ var base64EncodeOutputStream = function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2392
 
2393
+ var _buffer = 0;
2394
+ var _buflen = 0;
2395
+ var _length = 0;
2396
+ var _base64 = '';
2397
 
2398
+ var _this = {};
 
 
2399
 
2400
+ var writeEncoded = function(b) {
2401
+ _base64 += String.fromCharCode(encode(b & 0x3f) );
2402
+ };
 
 
2403
 
2404
+ var encode = function(n) {
2405
+ if (n < 0) {
2406
+ // error.
2407
+ } else if (n < 26) {
2408
+ return 0x41 + n;
2409
+ } else if (n < 52) {
2410
+ return 0x61 + (n - 26);
2411
+ } else if (n < 62) {
2412
+ return 0x30 + (n - 52);
2413
+ } else if (n == 62) {
2414
+ return 0x2b;
2415
+ } else if (n == 63) {
2416
+ return 0x2f;
2417
+ }
2418
+ throw 'n:' + n;
2419
+ };
2420
 
2421
+ _this.writeByte = function(n) {
 
 
 
 
2422
 
2423
+ _buffer = (_buffer << 8) | (n & 0xff);
2424
+ _buflen += 8;
2425
+ _length += 1;
 
 
 
 
 
2426
 
2427
+ while (_buflen >= 6) {
2428
+ writeEncoded(_buffer >>> (_buflen - 6) );
2429
+ _buflen -= 6;
2430
+ }
2431
+ };
2432
 
2433
+ _this.flush = function() {
 
2434
 
2435
+ if (_buflen > 0) {
2436
+ writeEncoded(_buffer << (6 - _buflen) );
2437
+ _buffer = 0;
2438
+ _buflen = 0;
2439
+ }
2440
 
2441
+ if (_length % 3 != 0) {
2442
+ // padding
2443
+ var padlen = 3 - _length % 3;
2444
+ for (var i = 0; i < padlen; i += 1) {
2445
+ _base64 += '=';
2446
+ }
2447
+ }
2448
+ };
2449
 
2450
+ _this.toString = function() {
2451
+ return _base64;
2452
+ };
 
2453
 
2454
+ return _this;
2455
+ };
2456
 
2457
+ //---------------------------------------------------------------------
2458
+ // base64DecodeInputStream
2459
+ //---------------------------------------------------------------------
2460
 
2461
+ var base64DecodeInputStream = function(str) {
2462
 
2463
+ var _str = str;
2464
+ var _pos = 0;
2465
+ var _buffer = 0;
2466
+ var _buflen = 0;
 
 
2467
 
2468
+ var _this = {};
 
2469
 
2470
+ _this.read = function() {
 
 
 
 
 
 
2471
 
2472
+ while (_buflen < 8) {
 
 
2473
 
2474
+ if (_pos >= _str.length) {
2475
+ if (_buflen == 0) {
2476
+ return -1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2477
  }
2478
+ throw 'unexpected end of file./' + _buflen;
2479
+ }
2480
 
2481
+ var c = _str.charAt(_pos);
2482
+ _pos += 1;
2483
 
2484
+ if (c == '=') {
2485
+ _buflen = 0;
2486
+ return -1;
2487
+ } else if (c.match(/^\s$/) ) {
2488
+ // ignore if whitespace.
2489
+ continue;
2490
+ }
2491
 
2492
+ _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );
2493
+ _buflen += 6;
2494
+ }
2495
 
2496
+ var n = (_buffer >>> (_buflen - 8) ) & 0xff;
2497
+ _buflen -= 8;
2498
+ return n;
2499
+ };
2500
 
2501
+ var decode = function(c) {
2502
+ if (0x41 <= c && c <= 0x5a) {
2503
+ return c - 0x41;
2504
+ } else if (0x61 <= c && c <= 0x7a) {
2505
+ return c - 0x61 + 26;
2506
+ } else if (0x30 <= c && c <= 0x39) {
2507
+ return c - 0x30 + 52;
2508
+ } else if (c == 0x2b) {
2509
+ return 62;
2510
+ } else if (c == 0x2f) {
2511
+ return 63;
2512
+ } else {
2513
+ throw 'c:' + c;
2514
+ }
2515
+ };
2516
 
2517
+ return _this;
2518
+ };
 
2519
 
2520
+ //---------------------------------------------------------------------
2521
+ // gifImage (B/W)
2522
+ //---------------------------------------------------------------------
2523
 
2524
+ var gifImage = function(width, height) {
 
2525
 
2526
+ var _width = width;
2527
+ var _height = height;
2528
+ var _data = new Array(width * height);
2529
 
2530
+ var _this = {};
 
2531
 
2532
+ _this.setPixel = function(x, y, pixel) {
2533
+ _data[y * _width + x] = pixel;
2534
+ };
2535
 
2536
+ _this.write = function(out) {
 
 
2537
 
2538
+ //---------------------------------
2539
+ // GIF Signature
2540
 
2541
+ out.writeString('GIF87a');
 
 
 
2542
 
2543
+ //---------------------------------
2544
+ // Screen Descriptor
 
 
2545
 
2546
+ out.writeShort(_width);
2547
+ out.writeShort(_height);
2548
 
2549
+ out.writeByte(0x80); // 2bit
2550
+ out.writeByte(0);
2551
+ out.writeByte(0);
 
 
 
2552
 
2553
+ //---------------------------------
2554
+ // Global Color Map
2555
 
2556
+ // black
2557
+ out.writeByte(0x00);
2558
+ out.writeByte(0x00);
2559
+ out.writeByte(0x00);
2560
 
2561
+ // white
2562
+ out.writeByte(0xff);
2563
+ out.writeByte(0xff);
2564
+ out.writeByte(0xff);
2565
 
2566
+ //---------------------------------
2567
+ // Image Descriptor
2568
 
2569
+ out.writeString(',');
2570
+ out.writeShort(0);
2571
+ out.writeShort(0);
2572
+ out.writeShort(_width);
2573
+ out.writeShort(_height);
2574
+ out.writeByte(0);
2575
 
2576
+ //---------------------------------
2577
+ // Local Color Map
 
 
 
2578
 
2579
+ //---------------------------------
2580
+ // Raster Data
 
2581
 
2582
+ var lzwMinCodeSize = 2;
2583
+ var raster = getLZWRaster(lzwMinCodeSize);
 
 
2584
 
2585
+ out.writeByte(lzwMinCodeSize);
2586
 
2587
+ var offset = 0;
 
 
2588
 
2589
+ while (raster.length - offset > 255) {
2590
+ out.writeByte(255);
2591
+ out.writeBytes(raster, offset, 255);
2592
+ offset += 255;
2593
+ }
2594
 
2595
+ out.writeByte(raster.length - offset);
2596
+ out.writeBytes(raster, offset, raster.length - offset);
2597
+ out.writeByte(0x00);
2598
 
2599
+ //---------------------------------
2600
+ // GIF Terminator
2601
+ out.writeString(';');
2602
+ };
2603
 
2604
+ var bitOutputStream = function(out) {
 
 
 
 
 
 
2605
 
2606
+ var _out = out;
2607
+ var _bitLength = 0;
2608
+ var _bitBuffer = 0;
2609
 
2610
+ var _this = {};
 
 
 
 
2611
 
2612
+ _this.write = function(data, length) {
 
2613
 
2614
+ if ( (data >>> length) != 0) {
2615
+ throw 'length over';
2616
+ }
2617
 
2618
+ while (_bitLength + length >= 8) {
2619
+ _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );
2620
+ length -= (8 - _bitLength);
2621
+ data >>>= (8 - _bitLength);
2622
+ _bitBuffer = 0;
2623
+ _bitLength = 0;
2624
+ }
2625
 
2626
+ _bitBuffer = (data << _bitLength) | _bitBuffer;
2627
+ _bitLength = _bitLength + length;
2628
+ };
2629
 
2630
+ _this.flush = function() {
2631
+ if (_bitLength > 0) {
2632
+ _out.writeByte(_bitBuffer);
2633
+ }
2634
+ };
2635
 
2636
+ return _this;
2637
+ };
2638
 
2639
+ var getLZWRaster = function(lzwMinCodeSize) {
 
2640
 
2641
+ var clearCode = 1 << lzwMinCodeSize;
2642
+ var endCode = (1 << lzwMinCodeSize) + 1;
2643
+ var bitLength = lzwMinCodeSize + 1;
2644
 
2645
+ // Setup LZWTable
2646
+ var table = lzwTable();
2647
 
2648
+ for (var i = 0; i < clearCode; i += 1) {
2649
+ table.add(String.fromCharCode(i) );
2650
+ }
2651
+ table.add(String.fromCharCode(clearCode) );
2652
+ table.add(String.fromCharCode(endCode) );
2653
 
2654
+ var byteOut = byteArrayOutputStream();
2655
+ var bitOut = bitOutputStream(byteOut);
2656
 
2657
+ // clear code
2658
+ bitOut.write(clearCode, bitLength);
2659
 
2660
+ var dataIndex = 0;
2661
 
2662
+ var s = String.fromCharCode(_data[dataIndex]);
2663
+ dataIndex += 1;
2664
 
2665
+ while (dataIndex < _data.length) {
2666
 
2667
+ var c = String.fromCharCode(_data[dataIndex]);
2668
+ dataIndex += 1;
2669
 
2670
+ if (table.contains(s + c) ) {
 
 
2671
 
2672
+ s = s + c;
 
2673
 
2674
+ } else {
 
 
2675
 
2676
  bitOut.write(table.indexOf(s), bitLength);
2677
 
2678
+ if (table.size() < 0xfff) {
 
2679
 
2680
+ if (table.size() == (1 << bitLength) ) {
2681
+ bitLength += 1;
2682
+ }
2683
 
2684
+ table.add(s + c);
2685
+ }
2686
 
2687
+ s = c;
2688
+ }
2689
+ }
2690
 
2691
+ bitOut.write(table.indexOf(s), bitLength);
 
2692
 
2693
+ // end code
2694
+ bitOut.write(endCode, bitLength);
2695
 
2696
+ bitOut.flush();
 
 
 
 
 
 
2697
 
2698
+ return byteOut.toByteArray();
2699
+ };
 
2700
 
2701
+ var lzwTable = function() {
 
 
2702
 
2703
+ var _map = {};
2704
+ var _size = 0;
 
2705
 
2706
+ var _this = {};
 
2707
 
2708
+ _this.add = function(key) {
2709
+ if (_this.contains(key) ) {
2710
+ throw 'dup key:' + key;
2711
+ }
2712
+ _map[key] = _size;
2713
+ _size += 1;
2714
  };
2715
 
2716
+ _this.size = function() {
2717
+ return _size;
2718
+ };
 
 
 
 
 
2719
 
2720
+ _this.indexOf = function(key) {
2721
+ return _map[key];
2722
+ };
2723
 
2724
+ _this.contains = function(key) {
2725
+ return typeof _map[key] != 'undefined';
2726
+ };
 
 
 
2727
 
2728
+ return _this;
2729
+ };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2730
 
2731
+ return _this;
2732
+ };
2733
 
2734
+ var createDataURL = function(width, height, getPixel) {
2735
+ var gif = gifImage(width, height);
2736
+ for (var y = 0; y < height; y += 1) {
2737
+ for (var x = 0; x < width; x += 1) {
2738
+ gif.setPixel(x, y, getPixel(x, y) );
2739
+ }
2740
+ }
2741
 
2742
+ var b = byteArrayOutputStream();
2743
+ gif.write(b);
2744
 
2745
+ var base64 = base64EncodeOutputStream();
2746
+ var bytes = b.toByteArray();
2747
+ for (var i = 0; i < bytes.length; i += 1) {
2748
+ base64.writeByte(bytes[i]);
2749
+ }
2750
+ base64.flush();
2751
+
2752
+ return 'data:image/gif;base64,' + base64;
2753
+ };
2754
+
2755
+ //---------------------------------------------------------------------
2756
+ // returns qrcode function.
2757
+
2758
+ return qrcode;
2759
+ }();
2760
+
2761
+ // multibyte support
2762
+ !function() {
2763
+
2764
+ qrcode.stringToBytesFuncs['UTF-8'] = function(s) {
2765
+ // http://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
2766
+ function toUTF8Array(str) {
2767
+ var utf8 = [];
2768
+ for (var i=0; i < str.length; i++) {
2769
+ var charcode = str.charCodeAt(i);
2770
+ if (charcode < 0x80) utf8.push(charcode);
2771
+ else if (charcode < 0x800) {
2772
+ utf8.push(0xc0 | (charcode >> 6),
2773
+ 0x80 | (charcode & 0x3f));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2774
  }
2775
+ else if (charcode < 0xd800 || charcode >= 0xe000) {
2776
+ utf8.push(0xe0 | (charcode >> 12),
2777
+ 0x80 | ((charcode>>6) & 0x3f),
2778
+ 0x80 | (charcode & 0x3f));
2779
+ }
2780
+ // surrogate pair
2781
+ else {
2782
+ i++;
2783
+ // UTF-16 encodes 0x10000-0x10FFFF by
2784
+ // subtracting 0x10000 and splitting the
2785
+ // 20 bits of 0x0-0xFFFFF into two halves
2786
+ charcode = 0x10000 + (((charcode & 0x3ff)<<10)
2787
+ | (str.charCodeAt(i) & 0x3ff));
2788
+ utf8.push(0xf0 | (charcode >>18),
2789
+ 0x80 | ((charcode>>12) & 0x3f),
2790
+ 0x80 | ((charcode>>6) & 0x3f),
2791
+ 0x80 | (charcode & 0x3f));
2792
+ }
2793
+ }
2794
+ return utf8;
2795
+ }
2796
+ return toUTF8Array(s);
2797
+ };
2798
+
2799
+ }();
2800
+
2801
+ (function (factory) {
2802
+ if (true) {
2803
+ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
2804
+ __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
2805
+ (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
2806
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
2807
+ } else {}
2808
+ }(function () {
2809
+ return qrcode;
2810
+ }));
2811
 
 
2812
 
2813
+ /***/ })
2814
+ /******/ ]);
2815
+ });
includes/jquery-qrcode/jquery-qrcode.min.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! jquery-qrcode v0.14.0 - https://larsjung.de/jquery-qrcode/ */
2
- !function(r){"use strict";function t(t,e,n,o){function a(r,t){return r-=o,t-=o,0>r||r>=c||0>t||t>=c?!1:f.isDark(r,t)}function i(r,t,e,n){var o=u.isDark,a=1/l;u.isDark=function(i,u){var f=u*a,c=i*a,l=f+a,g=c+a;return o(i,u)&&(r>l||f>e||t>g||c>n)}}var u={},f=r(n,e);f.addData(t),f.make(),o=o||0;var c=f.getModuleCount(),l=f.getModuleCount()+2*o;return u.text=t,u.level=e,u.version=n,u.moduleCount=l,u.isDark=a,u.addBlank=i,u}function e(r,e,n,o,a){n=Math.max(1,n||1),o=Math.min(40,o||40);for(var i=n;o>=i;i+=1)try{return t(r,e,i,a)}catch(u){}}function n(r,t,e){var n=e.size,o="bold "+e.mSize*n+"px "+e.fontname,a=w("<canvas/>")[0].getContext("2d");a.font=o;var i=a.measureText(e.label).width,u=e.mSize,f=i/n,c=(1-f)*e.mPosX,l=(1-u)*e.mPosY,g=c+f,s=l+u,v=.01;1===e.mode?r.addBlank(0,l-v,n,s+v):r.addBlank(c-v,l-v,g+v,s+v),t.fillStyle=e.fontcolor,t.font=o,t.fillText(e.label,c*n,l*n+.75*e.mSize*n)}function o(r,t,e){var n=e.size,o=e.image.naturalWidth||1,a=e.image.naturalHeight||1,i=e.mSize,u=i*o/a,f=(1-u)*e.mPosX,c=(1-i)*e.mPosY,l=f+u,g=c+i,s=.01;3===e.mode?r.addBlank(0,c-s,n,g+s):r.addBlank(f-s,c-s,l+s,g+s),t.drawImage(e.image,f*n,c*n,u*n,i*n)}function a(r,t,e){w(e.background).is("img")?t.drawImage(e.background,0,0,e.size,e.size):e.background&&(t.fillStyle=e.background,t.fillRect(e.left,e.top,e.size,e.size));var a=e.mode;1===a||2===a?n(r,t,e):(3===a||4===a)&&o(r,t,e)}function i(r,t,e,n,o,a,i,u){r.isDark(i,u)&&t.rect(n,o,a,a)}function u(r,t,e,n,o,a,i,u,f,c){i?r.moveTo(t+a,e):r.moveTo(t,e),u?(r.lineTo(n-a,e),r.arcTo(n,e,n,o,a)):r.lineTo(n,e),f?(r.lineTo(n,o-a),r.arcTo(n,o,t,o,a)):r.lineTo(n,o),c?(r.lineTo(t+a,o),r.arcTo(t,o,t,e,a)):r.lineTo(t,o),i?(r.lineTo(t,e+a),r.arcTo(t,e,n,e,a)):r.lineTo(t,e)}function f(r,t,e,n,o,a,i,u,f,c){i&&(r.moveTo(t+a,e),r.lineTo(t,e),r.lineTo(t,e+a),r.arcTo(t,e,t+a,e,a)),u&&(r.moveTo(n-a,e),r.lineTo(n,e),r.lineTo(n,e+a),r.arcTo(n,e,n-a,e,a)),f&&(r.moveTo(n-a,o),r.lineTo(n,o),r.lineTo(n,o-a),r.arcTo(n,o,n-a,o,a)),c&&(r.moveTo(t+a,o),r.lineTo(t,o),r.lineTo(t,o-a),r.arcTo(t,o,t+a,o,a))}function c(r,t,e,n,o,a,i,c){var l=r.isDark,g=n+a,s=o+a,v=e.radius*a,h=i-1,d=i+1,w=c-1,m=c+1,y=l(i,c),T=l(h,w),p=l(h,c),B=l(h,m),A=l(i,m),E=l(d,m),k=l(d,c),M=l(d,w),C=l(i,w);y?u(t,n,o,g,s,v,!p&&!C,!p&&!A,!k&&!A,!k&&!C):f(t,n,o,g,s,v,p&&C&&T,p&&A&&B,k&&A&&E,k&&C&&M)}function l(r,t,e){var n,o,a=r.moduleCount,u=e.size/a,f=i;for(e.radius>0&&e.radius<=.5&&(f=c),t.beginPath(),n=0;a>n;n+=1)for(o=0;a>o;o+=1){var l=e.left+o*u,g=e.top+n*u,s=u;f(r,t,e,l,g,s,n,o)}if(w(e.fill).is("img")){t.strokeStyle="rgba(0,0,0,0.5)",t.lineWidth=2,t.stroke();var v=t.globalCompositeOperation;t.globalCompositeOperation="destination-out",t.fill(),t.globalCompositeOperation=v,t.clip(),t.drawImage(e.fill,0,0,e.size,e.size),t.restore()}else t.fillStyle=e.fill,t.fill()}function g(r,t){var n=e(t.text,t.ecLevel,t.minVersion,t.maxVersion,t.quiet);if(!n)return null;var o=w(r).data("qrcode",n),i=o[0].getContext("2d");return a(n,i,t),l(n,i,t),o}function s(r){var t=w("<canvas/>").attr("width",r.size).attr("height",r.size);return g(t,r)}function v(r){return w("<img/>").attr("src",s(r)[0].toDataURL("image/png"))}function h(r){var t=e(r.text,r.ecLevel,r.minVersion,r.maxVersion,r.quiet);if(!t)return null;var n,o,a=r.size,i=r.background,u=Math.floor,f=t.moduleCount,c=u(a/f),l=u(.5*(a-c*f)),g={position:"relative",left:0,top:0,padding:0,margin:0,width:a,height:a},s={position:"absolute",padding:0,margin:0,width:c,height:c,"background-color":r.fill},v=w("<div/>").data("qrcode",t).css(g);for(i&&v.css("background-color",i),n=0;f>n;n+=1)for(o=0;f>o;o+=1)t.isDark(n,o)&&w("<div/>").css(s).css({left:l+o*c,top:l+n*c}).appendTo(v);return v}function d(r){return m&&"canvas"===r.render?s(r):m&&"image"===r.render?v(r):h(r)}var w=window.jQuery,m=function(){var r=document.createElement("canvas");return!(!r.getContext||!r.getContext("2d"))}(),y={render:"canvas",minVersion:1,maxVersion:40,ecLevel:"L",left:0,top:0,size:200,fill:"#000",background:null,text:"no text",radius:0,quiet:0,mode:0,mSize:.1,mPosX:.5,mPosY:.5,label:"no label",fontname:"sans",fontcolor:"#000",image:null};w.fn.qrcode=function(r){var t=w.extend({},y,r);return this.each(function(r,e){"canvas"===e.nodeName.toLowerCase()?g(e,t):w(e).append(d(t))})}}(function(){var r=function(){function r(t,e){if("undefined"==typeof t.length)throw new Error(t.length+"/"+e);var n=function(){for(var r=0;r<t.length&&0==t[r];)r+=1;for(var n=new Array(t.length-r+e),o=0;o<t.length-r;o+=1)n[o]=t[o+r];return n}(),o={};return o.getAt=function(r){return n[r]},o.getLength=function(){return n.length},o.multiply=function(t){for(var e=new Array(o.getLength()+t.getLength()-1),n=0;n<o.getLength();n+=1)for(var a=0;a<t.getLength();a+=1)e[n+a]^=i.gexp(i.glog(o.getAt(n))+i.glog(t.getAt(a)));return r(e,0)},o.mod=function(t){if(o.getLength()-t.getLength()<0)return o;for(var e=i.glog(o.getAt(0))-i.glog(t.getAt(0)),n=new Array(o.getLength()),a=0;a<o.getLength();a+=1)n[a]=o.getAt(a);for(var a=0;a<t.getLength();a+=1)n[a]^=i.gexp(i.glog(t.getAt(a))+e);return r(n,0).mod(t)},o}var t=function(t,e){var o=236,i=17,l=t,g=n[e],s=null,v=0,d=null,w=new Array,m={},y=function(r,t){v=4*l+17,s=function(r){for(var t=new Array(r),e=0;r>e;e+=1){t[e]=new Array(r);for(var n=0;r>n;n+=1)t[e][n]=null}return t}(v),T(0,0),T(v-7,0),T(0,v-7),A(),B(),k(r,t),l>=7&&E(r),null==d&&(d=D(l,g,w)),M(d,t)},T=function(r,t){for(var e=-1;7>=e;e+=1)if(!(-1>=r+e||r+e>=v))for(var n=-1;7>=n;n+=1)-1>=t+n||t+n>=v||(e>=0&&6>=e&&(0==n||6==n)||n>=0&&6>=n&&(0==e||6==e)||e>=2&&4>=e&&n>=2&&4>=n?s[r+e][t+n]=!0:s[r+e][t+n]=!1)},p=function(){for(var r=0,t=0,e=0;8>e;e+=1){y(!0,e);var n=a.getLostPoint(m);(0==e||r>n)&&(r=n,t=e)}return t},B=function(){for(var r=8;v-8>r;r+=1)null==s[r][6]&&(s[r][6]=r%2==0);for(var t=8;v-8>t;t+=1)null==s[6][t]&&(s[6][t]=t%2==0)},A=function(){for(var r=a.getPatternPosition(l),t=0;t<r.length;t+=1)for(var e=0;e<r.length;e+=1){var n=r[t],o=r[e];if(null==s[n][o])for(var i=-2;2>=i;i+=1)for(var u=-2;2>=u;u+=1)-2==i||2==i||-2==u||2==u||0==i&&0==u?s[n+i][o+u]=!0:s[n+i][o+u]=!1}},E=function(r){for(var t=a.getBCHTypeNumber(l),e=0;18>e;e+=1){var n=!r&&1==(t>>e&1);s[Math.floor(e/3)][e%3+v-8-3]=n}for(var e=0;18>e;e+=1){var n=!r&&1==(t>>e&1);s[e%3+v-8-3][Math.floor(e/3)]=n}},k=function(r,t){for(var e=g<<3|t,n=a.getBCHTypeInfo(e),o=0;15>o;o+=1){var i=!r&&1==(n>>o&1);6>o?s[o][8]=i:8>o?s[o+1][8]=i:s[v-15+o][8]=i}for(var o=0;15>o;o+=1){var i=!r&&1==(n>>o&1);8>o?s[8][v-o-1]=i:9>o?s[8][15-o-1+1]=i:s[8][15-o-1]=i}s[v-8][8]=!r},M=function(r,t){for(var e=-1,n=v-1,o=7,i=0,u=a.getMaskFunction(t),f=v-1;f>0;f-=2)for(6==f&&(f-=1);;){for(var c=0;2>c;c+=1)if(null==s[n][f-c]){var l=!1;i<r.length&&(l=1==(r[i]>>>o&1));var g=u(n,f-c);g&&(l=!l),s[n][f-c]=l,o-=1,-1==o&&(i+=1,o=7)}if(n+=e,0>n||n>=v){n-=e,e=-e;break}}},C=function(t,e){for(var n=0,o=0,i=0,u=new Array(e.length),f=new Array(e.length),c=0;c<e.length;c+=1){var l=e[c].dataCount,g=e[c].totalCount-l;o=Math.max(o,l),i=Math.max(i,g),u[c]=new Array(l);for(var s=0;s<u[c].length;s+=1)u[c][s]=255&t.getBuffer()[s+n];n+=l;var v=a.getErrorCorrectPolynomial(g),h=r(u[c],v.getLength()-1),d=h.mod(v);f[c]=new Array(v.getLength()-1);for(var s=0;s<f[c].length;s+=1){var w=s+d.getLength()-f[c].length;f[c][s]=w>=0?d.getAt(w):0}}for(var m=0,s=0;s<e.length;s+=1)m+=e[s].totalCount;for(var y=new Array(m),T=0,s=0;o>s;s+=1)for(var c=0;c<e.length;c+=1)s<u[c].length&&(y[T]=u[c][s],T+=1);for(var s=0;i>s;s+=1)for(var c=0;c<e.length;c+=1)s<f[c].length&&(y[T]=f[c][s],T+=1);return y},D=function(r,t,e){for(var n=u.getRSBlocks(r,t),c=f(),l=0;l<e.length;l+=1){var g=e[l];c.put(g.getMode(),4),c.put(g.getLength(),a.getLengthInBits(g.getMode(),r)),g.write(c)}for(var s=0,l=0;l<n.length;l+=1)s+=n[l].dataCount;if(c.getLengthInBits()>8*s)throw new Error("code length overflow. ("+c.getLengthInBits()+">"+8*s+")");for(c.getLengthInBits()+4<=8*s&&c.put(0,4);c.getLengthInBits()%8!=0;)c.putBit(!1);for(;;){if(c.getLengthInBits()>=8*s)break;if(c.put(o,8),c.getLengthInBits()>=8*s)break;c.put(i,8)}return C(c,n)};return m.addData=function(r){var t=c(r);w.push(t),d=null},m.isDark=function(r,t){if(0>r||r>=v||0>t||t>=v)throw new Error(r+","+t);return s[r][t]},m.getModuleCount=function(){return v},m.make=function(){y(!1,p())},m.createTableTag=function(r,t){r=r||2,t="undefined"==typeof t?4*r:t;var e="";e+='<table style="',e+=" border-width: 0px; border-style: none;",e+=" border-collapse: collapse;",e+=" padding: 0px; margin: "+t+"px;",e+='">',e+="<tbody>";for(var n=0;n<m.getModuleCount();n+=1){e+="<tr>";for(var o=0;o<m.getModuleCount();o+=1)e+='<td style="',e+=" border-width: 0px; border-style: none;",e+=" border-collapse: collapse;",e+=" padding: 0px; margin: 0px;",e+=" width: "+r+"px;",e+=" height: "+r+"px;",e+=" background-color: ",e+=m.isDark(n,o)?"#000000":"#ffffff",e+=";",e+='"/>';e+="</tr>"}return e+="</tbody>",e+="</table>"},m.createImgTag=function(r,t){r=r||2,t="undefined"==typeof t?4*r:t;var e=m.getModuleCount()*r+2*t,n=t,o=e-t;return h(e,e,function(t,e){if(t>=n&&o>t&&e>=n&&o>e){var a=Math.floor((t-n)/r),i=Math.floor((e-n)/r);return m.isDark(i,a)?0:1}return 1})},m};t.stringToBytes=function(r){for(var t=new Array,e=0;e<r.length;e+=1){var n=r.charCodeAt(e);t.push(255&n)}return t},t.createStringToBytes=function(r,t){var e=function(){for(var e=s(r),n=function(){var r=e.read();if(-1==r)throw new Error;return r},o=0,a={};;){var i=e.read();if(-1==i)break;var u=n(),f=n(),c=n(),l=String.fromCharCode(i<<8|u),g=f<<8|c;a[l]=g,o+=1}if(o!=t)throw new Error(o+" != "+t);return a}(),n="?".charCodeAt(0);return function(r){for(var t=new Array,o=0;o<r.length;o+=1){var a=r.charCodeAt(o);if(128>a)t.push(a);else{var i=e[r.charAt(o)];"number"==typeof i?(255&i)==i?t.push(i):(t.push(i>>>8),t.push(255&i)):t.push(n)}}return t}};var e={MODE_NUMBER:1,MODE_ALPHA_NUM:2,MODE_8BIT_BYTE:4,MODE_KANJI:8},n={L:1,M:0,Q:3,H:2},o={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7},a=function(){var t=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],n=1335,a=7973,u=21522,f={},c=function(r){for(var t=0;0!=r;)t+=1,r>>>=1;return t};return f.getBCHTypeInfo=function(r){for(var t=r<<10;c(t)-c(n)>=0;)t^=n<<c(t)-c(n);return(r<<10|t)^u},f.getBCHTypeNumber=function(r){for(var t=r<<12;c(t)-c(a)>=0;)t^=a<<c(t)-c(a);return r<<12|t},f.getPatternPosition=function(r){return t[r-1]},f.getMaskFunction=function(r){switch(r){case o.PATTERN000:return function(r,t){return(r+t)%2==0};case o.PATTERN001:return function(r,t){return r%2==0};case o.PATTERN010:return function(r,t){return t%3==0};case o.PATTERN011:return function(r,t){return(r+t)%3==0};case o.PATTERN100:return function(r,t){return(Math.floor(r/2)+Math.floor(t/3))%2==0};case o.PATTERN101:return function(r,t){return r*t%2+r*t%3==0};case o.PATTERN110:return function(r,t){return(r*t%2+r*t%3)%2==0};case o.PATTERN111:return function(r,t){return(r*t%3+(r+t)%2)%2==0};default:throw new Error("bad maskPattern:"+r)}},f.getErrorCorrectPolynomial=function(t){for(var e=r([1],0),n=0;t>n;n+=1)e=e.multiply(r([1,i.gexp(n)],0));return e},f.getLengthInBits=function(r,t){if(t>=1&&10>t)switch(r){case e.MODE_NUMBER:return 10;case e.MODE_ALPHA_NUM:return 9;case e.MODE_8BIT_BYTE:return 8;case e.MODE_KANJI:return 8;default:throw new Error("mode:"+r)}else if(27>t)switch(r){case e.MODE_NUMBER:return 12;case e.MODE_ALPHA_NUM:return 11;case e.MODE_8BIT_BYTE:return 16;case e.MODE_KANJI:return 10;default:throw new Error("mode:"+r)}else{if(!(41>t))throw new Error("type:"+t);switch(r){case e.MODE_NUMBER:return 14;case e.MODE_ALPHA_NUM:return 13;case e.MODE_8BIT_BYTE:return 16;case e.MODE_KANJI:return 12;default:throw new Error("mode:"+r)}}},f.getLostPoint=function(r){for(var t=r.getModuleCount(),e=0,n=0;t>n;n+=1)for(var o=0;t>o;o+=1){for(var a=0,i=r.isDark(n,o),u=-1;1>=u;u+=1)if(!(0>n+u||n+u>=t))for(var f=-1;1>=f;f+=1)0>o+f||o+f>=t||(0!=u||0!=f)&&i==r.isDark(n+u,o+f)&&(a+=1);a>5&&(e+=3+a-5)}for(var n=0;t-1>n;n+=1)for(var o=0;t-1>o;o+=1){var c=0;r.isDark(n,o)&&(c+=1),r.isDark(n+1,o)&&(c+=1),r.isDark(n,o+1)&&(c+=1),r.isDark(n+1,o+1)&&(c+=1),(0==c||4==c)&&(e+=3)}for(var n=0;t>n;n+=1)for(var o=0;t-6>o;o+=1)r.isDark(n,o)&&!r.isDark(n,o+1)&&r.isDark(n,o+2)&&r.isDark(n,o+3)&&r.isDark(n,o+4)&&!r.isDark(n,o+5)&&r.isDark(n,o+6)&&(e+=40);for(var o=0;t>o;o+=1)for(var n=0;t-6>n;n+=1)r.isDark(n,o)&&!r.isDark(n+1,o)&&r.isDark(n+2,o)&&r.isDark(n+3,o)&&r.isDark(n+4,o)&&!r.isDark(n+5,o)&&r.isDark(n+6,o)&&(e+=40);for(var l=0,o=0;t>o;o+=1)for(var n=0;t>n;n+=1)r.isDark(n,o)&&(l+=1);var g=Math.abs(100*l/t/t-50)/5;return e+=10*g},f}(),i=function(){for(var r=new Array(256),t=new Array(256),e=0;8>e;e+=1)r[e]=1<<e;for(var e=8;256>e;e+=1)r[e]=r[e-4]^r[e-5]^r[e-6]^r[e-8];for(var e=0;255>e;e+=1)t[r[e]]=e;var n={};return n.glog=function(r){if(1>r)throw new Error("glog("+r+")");return t[r]},n.gexp=function(t){for(;0>t;)t+=255;for(;t>=256;)t-=255;return r[t]},n}(),u=function(){var r=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12,7,37,13],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],t=function(r,t){var e={};return e.totalCount=r,e.dataCount=t,e},e={},o=function(t,e){switch(e){case n.L:return r[4*(t-1)+0];case n.M:return r[4*(t-1)+1];case n.Q:return r[4*(t-1)+2];case n.H:return r[4*(t-1)+3];default:return}};return e.getRSBlocks=function(r,e){var n=o(r,e);if("undefined"==typeof n)throw new Error("bad rs block @ typeNumber:"+r+"/errorCorrectLevel:"+e);for(var a=n.length/3,i=new Array,u=0;a>u;u+=1)for(var f=n[3*u+0],c=n[3*u+1],l=n[3*u+2],g=0;f>g;g+=1)i.push(t(c,l));return i},e}(),f=function(){var r=new Array,t=0,e={};return e.getBuffer=function(){return r},e.getAt=function(t){var e=Math.floor(t/8);return 1==(r[e]>>>7-t%8&1)},e.put=function(r,t){for(var n=0;t>n;n+=1)e.putBit(1==(r>>>t-n-1&1))},e.getLengthInBits=function(){return t},e.putBit=function(e){var n=Math.floor(t/8);r.length<=n&&r.push(0),e&&(r[n]|=128>>>t%8),t+=1},e},c=function(r){var n=e.MODE_8BIT_BYTE,o=t.stringToBytes(r),a={};return a.getMode=function(){return n},a.getLength=function(r){return o.length},a.write=function(r){for(var t=0;t<o.length;t+=1)r.put(o[t],8)},a},l=function(){var r=new Array,t={};return t.writeByte=function(t){r.push(255&t)},t.writeShort=function(r){t.writeByte(r),t.writeByte(r>>>8)},t.writeBytes=function(r,e,n){e=e||0,n=n||r.length;for(var o=0;n>o;o+=1)t.writeByte(r[o+e])},t.writeString=function(r){for(var e=0;e<r.length;e+=1)t.writeByte(r.charCodeAt(e))},t.toByteArray=function(){return r},t.toString=function(){var t="";t+="[";for(var e=0;e<r.length;e+=1)e>0&&(t+=","),t+=r[e];return t+="]"},t},g=function(){var r=0,t=0,e=0,n="",o={},a=function(r){n+=String.fromCharCode(i(63&r))},i=function(r){if(0>r);else{if(26>r)return 65+r;if(52>r)return 97+(r-26);if(62>r)return 48+(r-52);if(62==r)return 43;if(63==r)return 47}throw new Error("n:"+r)};return o.writeByte=function(n){for(r=r<<8|255&n,t+=8,e+=1;t>=6;)a(r>>>t-6),t-=6},o.flush=function(){if(t>0&&(a(r<<6-t),r=0,t=0),e%3!=0)for(var o=3-e%3,i=0;o>i;i+=1)n+="="},o.toString=function(){return n},o},s=function(r){var t=r,e=0,n=0,o=0,a={};a.read=function(){for(;8>o;){if(e>=t.length){if(0==o)return-1;throw new Error("unexpected end of file./"+o)}var r=t.charAt(e);if(e+=1,"="==r)return o=0,-1;r.match(/^\s$/)||(n=n<<6|i(r.charCodeAt(0)),o+=6)}var a=n>>>o-8&255;return o-=8,a};var i=function(r){if(r>=65&&90>=r)return r-65;if(r>=97&&122>=r)return r-97+26;if(r>=48&&57>=r)return r-48+52;if(43==r)return 62;if(47==r)return 63;throw new Error("c:"+r)};return a},v=function(r,t){var e=r,n=t,o=new Array(r*t),a={};a.setPixel=function(r,t,n){o[t*e+r]=n},a.write=function(r){r.writeString("GIF87a"),r.writeShort(e),r.writeShort(n),r.writeByte(128),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(0),r.writeByte(255),r.writeByte(255),r.writeByte(255),r.writeString(","),r.writeShort(0),r.writeShort(0),r.writeShort(e),r.writeShort(n),r.writeByte(0);var t=2,o=u(t);r.writeByte(t);for(var a=0;o.length-a>255;)r.writeByte(255),r.writeBytes(o,a,255),a+=255;r.writeByte(o.length-a),r.writeBytes(o,a,o.length-a),r.writeByte(0),r.writeString(";")};var i=function(r){var t=r,e=0,n=0,o={};return o.write=function(r,o){if(r>>>o!=0)throw new Error("length over");for(;e+o>=8;)t.writeByte(255&(r<<e|n)),o-=8-e,r>>>=8-e,n=0,e=0;n=r<<e|n,e+=o},o.flush=function(){e>0&&t.writeByte(n)},o},u=function(r){for(var t=1<<r,e=(1<<r)+1,n=r+1,a=f(),u=0;t>u;u+=1)a.add(String.fromCharCode(u));a.add(String.fromCharCode(t)),a.add(String.fromCharCode(e));var c=l(),g=i(c);g.write(t,n);var s=0,v=String.fromCharCode(o[s]);for(s+=1;s<o.length;){var h=String.fromCharCode(o[s]);s+=1,a.contains(v+h)?v+=h:(g.write(a.indexOf(v),n),a.size()<4095&&(a.size()==1<<n&&(n+=1),a.add(v+h)),v=h)}return g.write(a.indexOf(v),n),g.write(e,n),g.flush(),c.toByteArray()},f=function(){var r={},t=0,e={};return e.add=function(n){if(e.contains(n))throw new Error("dup key:"+n);r[n]=t,t+=1},e.size=function(){return t},e.indexOf=function(t){return r[t]},e.contains=function(t){return"undefined"!=typeof r[t]},e};return a},h=function(r,t,e,n){for(var o=v(r,t),a=0;t>a;a+=1)for(var i=0;r>i;i+=1)o.setPixel(i,a,e(i,a));var u=l();o.write(u);for(var f=g(),c=u.toByteArray(),s=0;s<c.length;s+=1)f.writeByte(c[s]);f.flush();var h="";return h+="<img",h+=' src="',h+="data:image/gif;base64,",h+=f,h+='"',h+=' width="',h+=r,h+='"',h+=' height="',h+=t,h+='"',n&&(h+=' alt="',h+=n,h+='"'),h+="/>"};return t}();return function(r){"function"==typeof define&&define.amd?define([],r):"object"==typeof exports&&(module.exports=r())}(function(){return r}),!function(r){r.stringToBytes=function(r){function t(r){for(var t=[],e=0;e<r.length;e++){var n=r.charCodeAt(e);128>n?t.push(n):2048>n?t.push(192|n>>6,128|63&n):55296>n||n>=57344?t.push(224|n>>12,128|n>>6&63,128|63&n):(e++,n=65536+((1023&n)<<10|1023&r.charCodeAt(e)),t.push(240|n>>18,128|n>>12&63,128|n>>6&63,128|63&n))}return t}return t(r)}}(r),r}());
1
+ /*! jquery-qrcode v0.17.0 - https://larsjung.de/jquery-qrcode/ */
2
+ !function(t,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define("jquery-qrcode",[],r):"object"==typeof exports?exports["jquery-qrcode"]=r():t["jquery-qrcode"]=r()}("undefined"!=typeof self?self:this,function(){return function(e){var n={};function o(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,o),r.l=!0,r.exports}return o.m=e,o.c=n,o.d=function(t,r,e){o.o(t,r)||Object.defineProperty(t,r,{enumerable:!0,get:e})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(r,t){if(1&t&&(r=o(r)),8&t)return r;if(4&t&&"object"==typeof r&&r&&r.__esModule)return r;var e=Object.create(null);if(o.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:r}),2&t&&"string"!=typeof r)for(var n in r)o.d(e,n,function(t){return r[t]}.bind(null,n));return e},o.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(r,"a",r),r},o.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},o.p="",o(o.s=0)}([function(v,t,p){(function(t){function c(t){return t&&"string"==typeof t.tagName&&"IMG"===t.tagName.toUpperCase()}function a(t,r,e,n){var o={},i=p(2);i.stringToBytes=i.stringToBytesFuncs["UTF-8"];var a=i(e,r);a.addData(t),a.make(),n=n||0;var u=a.getModuleCount(),s=u+2*n;return o.text=t,o.level=r,o.version=e,o.module_count=s,o.is_dark=function(t,r){return r-=n,0<=(t-=n)&&t<u&&0<=r&&r<u&&a.isDark(t,r)},o.add_blank=function(a,u,f,c){var l=o.is_dark,g=1/s;o.is_dark=function(t,r){var e=r*g,n=t*g,o=e+g,i=n+g;return l(t,r)&&(o<a||f<e||i<u||c<n)}},o}function h(t,r,e,n,o){e=Math.max(1,e||1),n=Math.min(40,n||40);for(var i=e;i<=n;i+=1)try{return a(t,r,i,o)}catch(t){}}function i(t,r,e){c(e.background)?r.drawImage(e.background,0,0,e.size,e.size):e.background&&(r.fillStyle=e.background,r.fillRect(e.left,e.top,e.size,e.size));var n=e.mode;1===n||2===n?function(t,r,e){var n=e.size,o="bold "+e.mSize*n+"px "+e.fontname,i=d("<canvas/>")[0].getContext("2d");i.font=o;var a=i.measureText(e.label).width,u=e.mSize,f=a/n,c=(1-f)*e.mPosX,l=(1-u)*e.mPosY,g=c+f,s=l+u;1===e.mode?t.add_blank(0,l-.01,n,s+.01):t.add_blank(c-.01,l-.01,.01+g,s+.01),r.fillStyle=e.fontcolor,r.font=o,r.fillText(e.label,c*n,l*n+.75*e.mSize*n)}(t,r,e):!c(e.image)||3!==n&&4!==n||function(t,r,e){var n=e.size,o=e.image.naturalWidth||1,i=e.image.naturalHeight||1,a=e.mSize,u=a*o/i,f=(1-u)*e.mPosX,c=(1-a)*e.mPosY,l=f+u,g=c+a;3===e.mode?t.add_blank(0,c-.01,n,g+.01):t.add_blank(f-.01,c-.01,.01+l,g+.01),r.drawImage(e.image,f*n,c*n,u*n,a*n)}(t,r,e)}function l(t,r,e,n,o,i,a,u){t.is_dark(a,u)&&r.rect(n,o,i,i)}function g(t,r,e,n,o,i,a,u){var f=t.is_dark,c=n+i,l=o+i,g=e.radius*i,s=a-1,h=a+1,d=u-1,v=u+1,p=f(a,u),w=f(s,d),y=f(s,u),m=f(s,v),b=f(a,v),k=f(h,v),C=f(h,u),B=f(h,d),x=f(a,d);p?function(t,r,e,n,o,i,a,u,f,c){a?t.moveTo(r+i,e):t.moveTo(r,e),u?(t.lineTo(n-i,e),t.arcTo(n,e,n,o,i)):t.lineTo(n,e),f?(t.lineTo(n,o-i),t.arcTo(n,o,r,o,i)):t.lineTo(n,o),c?(t.lineTo(r+i,o),t.arcTo(r,o,r,e,i)):t.lineTo(r,o),a?(t.lineTo(r,e+i),t.arcTo(r,e,n,e,i)):t.lineTo(r,e)}(r,n,o,c,l,g,!y&&!x,!y&&!b,!C&&!b,!C&&!x):function(t,r,e,n,o,i,a,u,f,c){a&&(t.moveTo(r+i,e),t.lineTo(r,e),t.lineTo(r,e+i),t.arcTo(r,e,r+i,e,i)),u&&(t.moveTo(n-i,e),t.lineTo(n,e),t.lineTo(n,e+i),t.arcTo(n,e,n-i,e,i)),f&&(t.moveTo(n-i,o),t.lineTo(n,o),t.lineTo(n,o-i),t.arcTo(n,o,n-i,o,i)),c&&(t.moveTo(r+i,o),t.lineTo(r,o),t.lineTo(r,o-i),t.arcTo(r,o,r+i,o,i))}(r,n,o,c,l,g,y&&x&&w,y&&b&&m,C&&b&&k,C&&x&&B)}function n(t,r){var e=h(r.text,r.ecLevel,r.minVersion,r.maxVersion,r.quiet);if(!e)return null;var n=d(t).data("qrcode",e),o=n[0].getContext("2d");return i(e,o,r),function(t,r,e){var n,o,i=t.module_count,a=e.size/i,u=l;for(0<e.radius&&e.radius<=.5&&(u=g),r.beginPath(),n=0;n<i;n+=1)for(o=0;o<i;o+=1)u(t,r,e,e.left+o*a,e.top+n*a,a,n,o);if(c(e.fill)){r.strokeStyle="rgba(0,0,0,0.5)",r.lineWidth=2,r.stroke();var f=r.globalCompositeOperation;r.globalCompositeOperation="destination-out",r.fill(),r.globalCompositeOperation=f,r.clip(),r.drawImage(e.fill,0,0,e.size,e.size),r.restore()}else r.fillStyle=e.fill,r.fill()}(e,o,r),n}function r(t){var r=d("<canvas/>").attr("width",t.size).attr("height",t.size);return n(r,t)}function o(t){return f&&"canvas"===t.render?r(t):f&&"image"===t.render?function(t){return d("<img/>").attr("src",r(t)[0].toDataURL("image/png"))}(t):function(t){var r=h(t.text,t.ecLevel,t.minVersion,t.maxVersion,t.quiet);if(!r)return null;var e,n,o=t.size,i=t.background,a=Math.floor,u=r.module_count,f=a(o/u),c=a(.5*(o-f*u)),l={position:"relative",left:0,top:0,padding:0,margin:0,width:o,height:o},g={position:"absolute",padding:0,margin:0,width:f,height:f,"background-color":t.fill},s=d("<div/>").data("qrcode",r).css(l);for(i&&s.css("background-color",i),e=0;e<u;e+=1)for(n=0;n<u;n+=1)r.is_dark(e,n)&&d("<div/>").css(g).css({left:c+n*f,top:c+e*f}).appendTo(s);return s}(t)}var e,u=t.window,d=u.jQuery,f=!(!(e=u.document.createElement("canvas")).getContext||!e.getContext("2d")),s={render:"canvas",minVersion:1,maxVersion:40,ecLevel:"L",left:0,top:0,size:200,fill:"#000",background:"#fff",text:"no text",radius:0,quiet:0,mode:0,mSize:.1,mPosX:.5,mPosY:.5,label:"no label",fontname:"sans",fontcolor:"#000",image:null};d.fn.qrcode=v.exports=function(t){var e=d.extend({},s,t);return this.each(function(t,r){"canvas"===r.nodeName.toLowerCase()?n(r,e):d(r).append(o(e))})}}).call(this,p(1))},function(t,r){var e;e=function(){return this}();try{e=e||new Function("return this")()}catch(t){"object"==typeof window&&(e=window)}t.exports=e},function(t,r,e){var n,o,i,a=function(){function i(t,r){function a(t,r){l=function(t){for(var r=new Array(t),e=0;e<t;e+=1){r[e]=new Array(t);for(var n=0;n<t;n+=1)r[e][n]=null}return r}(g=4*u+17),e(0,0),e(g-7,0),e(0,g-7),i(),o(),d(t,r),7<=u&&s(t),null==n&&(n=p(u,f,c)),v(n,r)}var u=t,f=w[r],l=null,g=0,n=null,c=[],h={},e=function(t,r){for(var e=-1;e<=7;e+=1)if(!(t+e<=-1||g<=t+e))for(var n=-1;n<=7;n+=1)r+n<=-1||g<=r+n||(l[t+e][r+n]=0<=e&&e<=6&&(0==n||6==n)||0<=n&&n<=6&&(0==e||6==e)||2<=e&&e<=4&&2<=n&&n<=4)},o=function(){for(var t=8;t<g-8;t+=1)null==l[t][6]&&(l[t][6]=t%2==0);for(var r=8;r<g-8;r+=1)null==l[6][r]&&(l[6][r]=r%2==0)},i=function(){for(var t=y.getPatternPosition(u),r=0;r<t.length;r+=1)for(var e=0;e<t.length;e+=1){var n=t[r],o=t[e];if(null==l[n][o])for(var i=-2;i<=2;i+=1)for(var a=-2;a<=2;a+=1)l[n+i][o+a]=-2==i||2==i||-2==a||2==a||0==i&&0==a}},s=function(t){for(var r=y.getBCHTypeNumber(u),e=0;e<18;e+=1){var n=!t&&1==(r>>e&1);l[Math.floor(e/3)][e%3+g-8-3]=n}for(e=0;e<18;e+=1){n=!t&&1==(r>>e&1);l[e%3+g-8-3][Math.floor(e/3)]=n}},d=function(t,r){for(var e=f<<3|r,n=y.getBCHTypeInfo(e),o=0;o<15;o+=1){var i=!t&&1==(n>>o&1);o<6?l[o][8]=i:o<8?l[o+1][8]=i:l[g-15+o][8]=i}for(o=0;o<15;o+=1){i=!t&&1==(n>>o&1);o<8?l[8][g-o-1]=i:o<9?l[8][15-o-1+1]=i:l[8][15-o-1]=i}l[g-8][8]=!t},v=function(t,r){for(var e=-1,n=g-1,o=7,i=0,a=y.getMaskFunction(r),u=g-1;0<u;u-=2)for(6==u&&(u-=1);;){for(var f=0;f<2;f+=1)if(null==l[n][u-f]){var c=!1;i<t.length&&(c=1==(t[i]>>>o&1)),a(n,u-f)&&(c=!c),l[n][u-f]=c,-1==(o-=1)&&(i+=1,o=7)}if((n+=e)<0||g<=n){n-=e,e=-e;break}}},p=function(t,r,e){for(var n=C.getRSBlocks(t,r),o=B(),i=0;i<e.length;i+=1){var a=e[i];o.put(a.getMode(),4),o.put(a.getLength(),y.getLengthInBits(a.getMode(),t)),a.write(o)}var u=0;for(i=0;i<n.length;i+=1)u+=n[i].dataCount;if(o.getLengthInBits()>8*u)throw"code length overflow. ("+o.getLengthInBits()+">"+8*u+")";for(o.getLengthInBits()+4<=8*u&&o.put(0,4);o.getLengthInBits()%8!=0;)o.putBit(!1);for(;!(o.getLengthInBits()>=8*u||(o.put(236,8),o.getLengthInBits()>=8*u));)o.put(17,8);return function(t,r){for(var e=0,n=0,o=0,i=new Array(r.length),a=new Array(r.length),u=0;u<r.length;u+=1){var f=r[u].dataCount,c=r[u].totalCount-f;n=Math.max(n,f),o=Math.max(o,c),i[u]=new Array(f);for(var l=0;l<i[u].length;l+=1)i[u][l]=255&t.getBuffer()[l+e];e+=f;var g=y.getErrorCorrectPolynomial(c),s=m(i[u],g.getLength()-1).mod(g);for(a[u]=new Array(g.getLength()-1),l=0;l<a[u].length;l+=1){var h=l+s.getLength()-a[u].length;a[u][l]=0<=h?s.getAt(h):0}}var d=0;for(l=0;l<r.length;l+=1)d+=r[l].totalCount;var v=new Array(d),p=0;for(l=0;l<n;l+=1)for(u=0;u<r.length;u+=1)l<i[u].length&&(v[p]=i[u][l],p+=1);for(l=0;l<o;l+=1)for(u=0;u<r.length;u+=1)l<a[u].length&&(v[p]=a[u][l],p+=1);return v}(o,n)};return h.addData=function(t,r){var e=null;switch(r=r||"Byte"){case"Numeric":e=x(t);break;case"Alphanumeric":e=T(t);break;case"Byte":e=M(t);break;case"Kanji":e=A(t);break;default:throw"mode:"+r}c.push(e),n=null},h.isDark=function(t,r){if(t<0||g<=t||r<0||g<=r)throw t+","+r;return l[t][r]},h.getModuleCount=function(){return g},h.make=function(){if(u<1){for(var t=1;t<40;t++){for(var r=C.getRSBlocks(t,f),e=B(),n=0;n<c.length;n++){var o=c[n];e.put(o.getMode(),4),e.put(o.getLength(),y.getLengthInBits(o.getMode(),t)),o.write(e)}var i=0;for(n=0;n<r.length;n++)i+=r[n].dataCount;if(e.getLengthInBits()<=8*i)break}u=t}a(!1,function(){for(var t=0,r=0,e=0;e<8;e+=1){a(!0,e);var n=y.getLostPoint(h);(0==e||n<t)&&(t=n,r=e)}return r}())},h.createTableTag=function(t,r){t=t||2;var e="";e+='<table style="',e+=" border-width: 0px; border-style: none;",e+=" border-collapse: collapse;",e+=" padding: 0px; margin: "+(r=void 0===r?4*t:r)+"px;",e+='">',e+="<tbody>";for(var n=0;n<h.getModuleCount();n+=1){e+="<tr>";for(var o=0;o<h.getModuleCount();o+=1)e+='<td style="',e+=" border-width: 0px; border-style: none;",e+=" border-collapse: collapse;",e+=" padding: 0px; margin: 0px;",e+=" width: "+t+"px;",e+=" height: "+t+"px;",e+=" background-color: ",e+=h.isDark(n,o)?"#000000":"#ffffff",e+=";",e+='"/>';e+="</tr>"}return e+="</tbody>",e+="</table>"},h.createSvgTag=function(t,r){var e={};"object"==typeof t&&(t=(e=t).cellSize,r=e.margin),t=t||2,r=void 0===r?4*t:r;var n,o,i,a,u=h.getModuleCount()*t+2*r,f="";for(a="l"+t+",0 0,"+t+" -"+t+",0 0,-"+t+"z ",f+='<svg version="1.1" xmlns="http://www.w3.org/2000/svg"',f+=e.scalable?"":' width="'+u+'px" height="'+u+'px"',f+=' viewBox="0 0 '+u+" "+u+'" ',f+=' preserveAspectRatio="xMinYMin meet">',f+='<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>',f+='<path d="',o=0;o<h.getModuleCount();o+=1)for(i=o*t+r,n=0;n<h.getModuleCount();n+=1)h.isDark(o,n)&&(f+="M"+(n*t+r)+","+i+a);return f+='" stroke="transparent" fill="black"/>',f+="</svg>"},h.createDataURL=function(o,t){o=o||2,t=void 0===t?4*o:t;var r=h.getModuleCount()*o+2*t,i=t,a=r-t;return L(r,r,function(t,r){if(i<=t&&t<a&&i<=r&&r<a){var e=Math.floor((t-i)/o),n=Math.floor((r-i)/o);return h.isDark(n,e)?0:1}return 1})},h.createImgTag=function(t,r,e){t=t||2,r=void 0===r?4*t:r;var n=h.getModuleCount()*t+2*r,o="";return o+="<img",o+=' src="',o+=h.createDataURL(t,r),o+='"',o+=' width="',o+=n,o+='"',o+=' height="',o+=n,o+='"',e&&(o+=' alt="',o+=e,o+='"'),o+="/>"},h.createASCII=function(t,r){if((t=t||1)<2)return function(t){t=void 0===t?2:t;var r,e,n,o,i,a=1*h.getModuleCount()+2*t,u=t,f=a-t,c={"██":"█","█ ":"▀"," █":"▄"," ":" "},l={"██":"▀","█ ":"▀"," █":" "," ":" "},g="";for(r=0;r<a;r+=2){for(n=Math.floor((r-u)/1),o=Math.floor((r+1-u)/1),e=0;e<a;e+=1)i="█",u<=e&&e<f&&u<=r&&r<f&&h.isDark(n,Math.floor((e-u)/1))&&(i=" "),u<=e&&e<f&&u<=r+1&&r+1<f&&h.isDark(o,Math.floor((e-u)/1))?i+=" ":i+="█",g+=t<1&&f<=r+1?l[i]:c[i];g+="\n"}return a%2&&0<t?g.substring(0,g.length-a-1)+Array(1+a).join("▀"):g.substring(0,g.length-1)}(r);t-=1,r=void 0===r?2*t:r;var e,n,o,i,a=h.getModuleCount()*t+2*r,u=r,f=a-r,c=Array(t+1).join("██"),l=Array(t+1).join(" "),g="",s="";for(e=0;e<a;e+=1){for(o=Math.floor((e-u)/t),s="",n=0;n<a;n+=1)i=1,u<=n&&n<f&&u<=e&&e<f&&h.isDark(o,Math.floor((n-u)/t))&&(i=0),s+=i?c:l;for(o=0;o<t;o+=1)g+=s+"\n"}return g.substring(0,g.length-1)},h.renderTo2dContext=function(t,r){r=r||2;for(var e=h.getModuleCount(),n=0;n<e;n++)for(var o=0;o<e;o++)t.fillStyle=h.isDark(n,o)?"black":"white",t.fillRect(n*r,o*r,r,r)},h}i.stringToBytes=(i.stringToBytesFuncs={default:function(t){for(var r=[],e=0;e<t.length;e+=1){var n=t.charCodeAt(e);r.push(255&n)}return r}}).default,i.createStringToBytes=function(u,f){var i=function(){function t(){var t=r.read();if(-1==t)throw"eof";return t}for(var r=S(u),e=0,n={};;){var o=r.read();if(-1==o)break;var i=t(),a=t()<<8|t();n[String.fromCharCode(o<<8|i)]=a,e+=1}if(e!=f)throw e+" != "+f;return n}(),a="?".charCodeAt(0);return function(t){for(var r=[],e=0;e<t.length;e+=1){var n=t.charCodeAt(e);if(n<128)r.push(n);else{var o=i[t.charAt(e)];"number"==typeof o?(255&o)==o?r.push(o):(r.push(o>>>8),r.push(255&o)):r.push(a)}}return r}};var a=1,u=2,o=4,f=8,w={L:1,M:0,Q:3,H:2},n=0,c=1,l=2,g=3,s=4,h=5,d=6,v=7,y=function(){function e(t){for(var r=0;0!=t;)r+=1,t>>>=1;return r}var r=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],t={};return t.getBCHTypeInfo=function(t){for(var r=t<<10;0<=e(r)-e(1335);)r^=1335<<e(r)-e(1335);return 21522^(t<<10|r)},t.getBCHTypeNumber=function(t){for(var r=t<<12;0<=e(r)-e(7973);)r^=7973<<e(r)-e(7973);return t<<12|r},t.getPatternPosition=function(t){return r[t-1]},t.getMaskFunction=function(t){switch(t){case n:return function(t,r){return(t+r)%2==0};case c:return function(t,r){return t%2==0};case l:return function(t,r){return r%3==0};case g:return function(t,r){return(t+r)%3==0};case s:return function(t,r){return(Math.floor(t/2)+Math.floor(r/3))%2==0};case h:return function(t,r){return t*r%2+t*r%3==0};case d:return function(t,r){return(t*r%2+t*r%3)%2==0};case v:return function(t,r){return(t*r%3+(t+r)%2)%2==0};default:throw"bad maskPattern:"+t}},t.getErrorCorrectPolynomial=function(t){for(var r=m([1],0),e=0;e<t;e+=1)r=r.multiply(m([1,p.gexp(e)],0));return r},t.getLengthInBits=function(t,r){if(1<=r&&r<10)switch(t){case a:return 10;case u:return 9;case o:case f:return 8;default:throw"mode:"+t}else if(r<27)switch(t){case a:return 12;case u:return 11;case o:return 16;case f:return 10;default:throw"mode:"+t}else{if(!(r<41))throw"type:"+r;switch(t){case a:return 14;case u:return 13;case o:return 16;case f:return 12;default:throw"mode:"+t}}},t.getLostPoint=function(t){for(var r=t.getModuleCount(),e=0,n=0;n<r;n+=1)for(var o=0;o<r;o+=1){for(var i=0,a=t.isDark(n,o),u=-1;u<=1;u+=1)if(!(n+u<0||r<=n+u))for(var f=-1;f<=1;f+=1)o+f<0||r<=o+f||0==u&&0==f||a==t.isDark(n+u,o+f)&&(i+=1);5<i&&(e+=3+i-5)}for(n=0;n<r-1;n+=1)for(o=0;o<r-1;o+=1){var c=0;t.isDark(n,o)&&(c+=1),t.isDark(n+1,o)&&(c+=1),t.isDark(n,o+1)&&(c+=1),t.isDark(n+1,o+1)&&(c+=1),0!=c&&4!=c||(e+=3)}for(n=0;n<r;n+=1)for(o=0;o<r-6;o+=1)t.isDark(n,o)&&!t.isDark(n,o+1)&&t.isDark(n,o+2)&&t.isDark(n,o+3)&&t.isDark(n,o+4)&&!t.isDark(n,o+5)&&t.isDark(n,o+6)&&(e+=40);for(o=0;o<r;o+=1)for(n=0;n<r-6;n+=1)t.isDark(n,o)&&!t.isDark(n+1,o)&&t.isDark(n+2,o)&&t.isDark(n+3,o)&&t.isDark(n+4,o)&&!t.isDark(n+5,o)&&t.isDark(n+6,o)&&(e+=40);var l=0;for(o=0;o<r;o+=1)for(n=0;n<r;n+=1)t.isDark(n,o)&&(l+=1);return e+=10*(Math.abs(100*l/r/r-50)/5)},t}(),p=function(){for(var r=new Array(256),e=new Array(256),t=0;t<8;t+=1)r[t]=1<<t;for(t=8;t<256;t+=1)r[t]=r[t-4]^r[t-5]^r[t-6]^r[t-8];for(t=0;t<255;t+=1)e[r[t]]=t;var n={glog:function(t){if(t<1)throw"glog("+t+")";return e[t]},gexp:function(t){for(;t<0;)t+=255;for(;256<=t;)t-=255;return r[t]}};return n}();function m(n,o){if(void 0===n.length)throw n.length+"/"+o;var r=function(){for(var t=0;t<n.length&&0==n[t];)t+=1;for(var r=new Array(n.length-t+o),e=0;e<n.length-t;e+=1)r[e]=n[e+t];return r}(),i={getAt:function(t){return r[t]},getLength:function(){return r.length},multiply:function(t){for(var r=new Array(i.getLength()+t.getLength()-1),e=0;e<i.getLength();e+=1)for(var n=0;n<t.getLength();n+=1)r[e+n]^=p.gexp(p.glog(i.getAt(e))+p.glog(t.getAt(n)));return m(r,0)},mod:function(t){if(i.getLength()-t.getLength()<0)return i;for(var r=p.glog(i.getAt(0))-p.glog(t.getAt(0)),e=new Array(i.getLength()),n=0;n<i.getLength();n+=1)e[n]=i.getAt(n);for(n=0;n<t.getLength();n+=1)e[n]^=p.gexp(p.glog(t.getAt(n))+r);return m(e,0).mod(t)}};return i}function b(){var e=[],o={writeByte:function(t){e.push(255&t)},writeShort:function(t){o.writeByte(t),o.writeByte(t>>>8)},writeBytes:function(t,r,e){r=r||0,e=e||t.length;for(var n=0;n<e;n+=1)o.writeByte(t[n+r])},writeString:function(t){for(var r=0;r<t.length;r+=1)o.writeByte(t.charCodeAt(r))},toByteArray:function(){return e},toString:function(){var t="";t+="[";for(var r=0;r<e.length;r+=1)0<r&&(t+=","),t+=e[r];return t+="]"}};return o}var k,t,C=(k=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12,7,37,13],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]],(t={}).getRSBlocks=function(t,r){var e=function(t,r){switch(r){case w.L:return k[4*(t-1)+0];case w.M:return k[4*(t-1)+1];case w.Q:return k[4*(t-1)+2];case w.H:return k[4*(t-1)+3];default:return}}(t,r);if(void 0===e)throw"bad rs block @ typeNumber:"+t+"/errorCorrectionLevel:"+r;for(var n,o,i=e.length/3,a=[],u=0;u<i;u+=1)for(var f=e[3*u+0],c=e[3*u+1],l=e[3*u+2],g=0;g<f;g+=1)a.push((n=l,o=void 0,(o={}).totalCount=c,o.dataCount=n,o));return a},t),B=function(){var e=[],n=0,o={getBuffer:function(){return e},getAt:function(t){var r=Math.floor(t/8);return 1==(e[r]>>>7-t%8&1)},put:function(t,r){for(var e=0;e<r;e+=1)o.putBit(1==(t>>>r-e-1&1))},getLengthInBits:function(){return n},putBit:function(t){var r=Math.floor(n/8);e.length<=r&&e.push(0),t&&(e[r]|=128>>>n%8),n+=1}};return o},x=function(t){var r=a,n=t,e={getMode:function(){return r},getLength:function(t){return n.length},write:function(t){for(var r=n,e=0;e+2<r.length;)t.put(o(r.substring(e,e+3)),10),e+=3;e<r.length&&(r.length-e==1?t.put(o(r.substring(e,e+1)),4):r.length-e==2&&t.put(o(r.substring(e,e+2)),7))}},o=function(t){for(var r=0,e=0;e<t.length;e+=1)r=10*r+i(t.charAt(e));return r},i=function(t){if("0"<=t&&t<="9")return t.charCodeAt(0)-"0".charCodeAt(0);throw"illegal char :"+t};return e},T=function(t){var r=u,n=t,e={getMode:function(){return r},getLength:function(t){return n.length},write:function(t){for(var r=n,e=0;e+1<r.length;)t.put(45*o(r.charAt(e))+o(r.charAt(e+1)),11),e+=2;e<r.length&&t.put(o(r.charAt(e)),6)}},o=function(t){if("0"<=t&&t<="9")return t.charCodeAt(0)-"0".charCodeAt(0);if("A"<=t&&t<="Z")return t.charCodeAt(0)-"A".charCodeAt(0)+10;switch(t){case" ":return 36;case"$":return 37;case"%":return 38;case"*":return 39;case"+":return 40;case"-":return 41;case".":return 42;case"/":return 43;case":":return 44;default:throw"illegal char :"+t}};return e},M=function(t){var r=o,e=i.stringToBytes(t),n={getMode:function(){return r},getLength:function(t){return e.length},write:function(t){for(var r=0;r<e.length;r+=1)t.put(e[r],8)}};return n},A=function(t){var r=f,n=i.stringToBytesFuncs.SJIS;if(!n)throw"sjis not supported.";!function(t,r){var e=n("友");if(2!=e.length||38726!=(e[0]<<8|e[1]))throw"sjis not supported."}();var o=n(t),e={getMode:function(){return r},getLength:function(t){return~~(o.length/2)},write:function(t){for(var r=o,e=0;e+1<r.length;){var n=(255&r[e])<<8|255&r[e+1];if(33088<=n&&n<=40956)n-=33088;else{if(!(57408<=n&&n<=60351))throw"illegal char at "+(e+1)+"/"+n;n-=49472}n=192*(n>>>8&255)+(255&n),t.put(n,13),e+=2}if(e<r.length)throw"illegal char at "+(e+1)}};return e},S=function(t){var e=t,n=0,o=0,i=0,r={read:function(){for(;i<8;){if(n>=e.length){if(0==i)return-1;throw"unexpected end of file./"+i}var t=e.charAt(n);if(n+=1,"="==t)return i=0,-1;t.match(/^\s$/)||(o=o<<6|a(t.charCodeAt(0)),i+=6)}var r=o>>>i-8&255;return i-=8,r}},a=function(t){if(65<=t&&t<=90)return t-65;if(97<=t&&t<=122)return t-97+26;if(48<=t&&t<=57)return t-48+52;if(43==t)return 62;if(47==t)return 63;throw"c:"+t};return r},L=function(t,r,e){for(var n=function(t,r){var n=t,o=r,g=new Array(t*r),e={setPixel:function(t,r,e){g[r*n+t]=e},write:function(t){t.writeString("GIF87a"),t.writeShort(n),t.writeShort(o),t.writeByte(128),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(0),t.writeByte(255),t.writeByte(255),t.writeByte(255),t.writeString(","),t.writeShort(0),t.writeShort(0),t.writeShort(n),t.writeShort(o),t.writeByte(0);var r=i(2);t.writeByte(2);for(var e=0;255<r.length-e;)t.writeByte(255),t.writeBytes(r,e,255),e+=255;t.writeByte(r.length-e),t.writeBytes(r,e,r.length-e),t.writeByte(0),t.writeString(";")}},i=function(t){for(var r=1<<t,e=1+(1<<t),n=t+1,o=s(),i=0;i<r;i+=1)o.add(String.fromCharCode(i));o.add(String.fromCharCode(r)),o.add(String.fromCharCode(e));var a=b(),u=function(t){var e=t,n=0,o=0,r={write:function(t,r){if(t>>>r!=0)throw"length over";for(;8<=n+r;)e.writeByte(255&(t<<n|o)),r-=8-n,t>>>=8-n,n=o=0;o|=t<<n,n+=r},flush:function(){0<n&&e.writeByte(o)}};return r}(a);u.write(r,n);var f=0,c=String.fromCharCode(g[f]);for(f+=1;f<g.length;){var l=String.fromCharCode(g[f]);f+=1,o.contains(c+l)?c+=l:(u.write(o.indexOf(c),n),o.size()<4095&&(o.size()==1<<n&&(n+=1),o.add(c+l)),c=l)}return u.write(o.indexOf(c),n),u.write(e,n),u.flush(),a.toByteArray()},s=function(){var r={},e=0,n={add:function(t){if(n.contains(t))throw"dup key:"+t;r[t]=e,e+=1},size:function(){return e},indexOf:function(t){return r[t]},contains:function(t){return void 0!==r[t]}};return n};return e}(t,r),o=0;o<r;o+=1)for(var i=0;i<t;i+=1)n.setPixel(i,o,e(i,o));var a=b();n.write(a);for(var u=function(){function e(t){a+=String.fromCharCode(r(63&t))}var n=0,o=0,i=0,a="",t={},r=function(t){if(t<0);else{if(t<26)return 65+t;if(t<52)return t-26+97;if(t<62)return t-52+48;if(62==t)return 43;if(63==t)return 47}throw"n:"+t};return t.writeByte=function(t){for(n=n<<8|255&t,o+=8,i+=1;6<=o;)e(n>>>o-6),o-=6},t.flush=function(){if(0<o&&(e(n<<6-o),o=n=0),i%3!=0)for(var t=3-i%3,r=0;r<t;r+=1)a+="="},t.toString=function(){return a},t}(),f=a.toByteArray(),c=0;c<f.length;c+=1)u.writeByte(f[c]);return u.flush(),"data:image/gif;base64,"+u};return i}();a.stringToBytesFuncs["UTF-8"]=function(t){return function(t){for(var r=[],e=0;e<t.length;e++){var n=t.charCodeAt(e);n<128?r.push(n):n<2048?r.push(192|n>>6,128|63&n):n<55296||57344<=n?r.push(224|n>>12,128|n>>6&63,128|63&n):(e++,n=65536+((1023&n)<<10|1023&t.charCodeAt(e)),r.push(240|n>>18,128|n>>12&63,128|n>>6&63,128|63&n))}return r}(t)},o=[],void 0===(i="function"==typeof(n=function(){return a})?n.apply(r,o):n)||(t.exports=i)}])});
includes/js/settings_page.js CHANGED
@@ -52,6 +52,10 @@ jQuery(document).ready(function () {
52
  ajaxCall("dissmissfeedback",".feedback-notice",true);
53
  });
54
 
 
 
 
 
55
  $(".whitelist_self").click(function(){
56
  ajaxCall("whitelistself",".whitelistself-notice",true);
57
  });
52
  ajaxCall("dissmissfeedback",".feedback-notice",true);
53
  });
54
 
55
+ $(".smtpsetup").click(function(){
56
+ ajaxCall("dissmissSMTP",".smtpsetup-notice",true);
57
+ });
58
+
59
  $(".whitelist_self").click(function(){
60
  ajaxCall("whitelistself",".whitelistself-notice",true);
61
  });
miniorange_2_factor_settings.php CHANGED
@@ -3,14 +3,15 @@
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/Authy/LastPass Authenticator, QR Code, Push Notification, Soft Token and Security Questions(KBA) for 1 User in the free version of the plugin.
6
- * Version: 5.3.23
7
  * Author: miniOrange
8
  * Author URI: https://miniorange.com
9
  * License: GPL2
10
  */
11
- define( 'MO_HOST_NAME', 'https://login.xecurify.com' );
12
- define( 'MO2F_VERSION', '5.3.23' );
13
- define( 'MO2F_TEST_MODE', false );
 
14
  class Miniorange_twoFactor{
15
 
16
  function __construct()
@@ -22,8 +23,14 @@
22
  add_action( 'admin_enqueue_scripts' , array( $this, 'mo_wpns_settings_script' ) );
23
  add_action( 'wpns_show_message' , array( $this, 'mo_show_message' ), 1 , 2 );
24
  add_action( 'wp_footer' , array( $this, 'footer_link' ),100 );
25
- add_action( 'admin_footer', array( $this, 'feedback_request' ) );
26
- add_action('admin_notices',array( $this, 'mo_wpns_malware_notices' ) );
 
 
 
 
 
 
27
  if(get_option('mo2f_disable_file_editing')) define('DISALLOW_FILE_EDIT', true);
28
  $this->includes();
29
  if(get_option("mo_wpns_2fa_with_network_security"))
@@ -37,7 +44,7 @@
37
  if ( 'plugins.php' != basename( $_SERVER['PHP_SELF'] ) ) {
38
  return;
39
  }
40
- global $dirName;
41
 
42
  $email = get_option("mo2f_email");
43
  if(empty($email)){
@@ -51,7 +58,7 @@
51
  wp_enqueue_script( 'utils' );
52
  wp_enqueue_style( 'mo_wpns_admin_plugins_page_style', plugins_url( '/includes/css/style_settings.css?ver=4.8.60', __FILE__ ) );
53
 
54
- include $dirName . 'views'.DIRECTORY_SEPARATOR.'feedback_form.php';;
55
 
56
  }
57
  function mo_wpns_malware_notices(){
@@ -91,63 +98,89 @@
91
  }else{
92
  $flag_plugin=1;
93
  }
94
- $days =(time()-get_option('mo_wpns_last_scan_time'))/(60*60*24);
 
95
  $days = (int)$days;
96
 
97
- $day_infected= (time()-get_option('infected_dismiss'))/(60*60*24);
98
  $day_infected = floor($day_infected);
99
- $day_weekly= (time()-get_option('weekly_dismiss'))/(60*60*24);
100
  $day_weekly = floor($day_weekly);
101
 
102
-
103
- if(get_option('mo_wpns_2fa_with_network_security'))
104
  {
105
- if(!get_option('donot_show_infected_file_notice') && (get_option('mo_wpns_infected_files') != 0) && ($day_infected >= 1)){
106
- do_action('wpns_show_message',MoWpnsMessages::showMessage('INFECTED_FILE'),'CUSTOM_MESSAGE');
107
- }else if(!get_option('donot_show_new_plugin_theme_notice') && ($flag_plugin || $flag_theme)){
108
- do_action('wpns_show_message',MoWpnsMessages::showMessage('NEW_PLUGIN_THEME_CHECK'),'CUSTOM_MESSAGE');
109
- }else if(!get_option('donot_show_weekly_scan_notice') && ($days >= 7) && ($day_weekly >= 1)){
110
- do_action('wpns_show_message',MoWpnsMessages::showMessage('WEEKLY_SCAN_CHECK'),'CUSTOM_MESSAGE');
111
- }
112
- }
113
- }
114
-
115
  function mo_wpns_widget_menu()
116
  {
117
- $menu_slug = 'mo_2fa_two_fa';
118
-
119
- add_menu_page ( 'miniOrange 2-Factor' , 'miniOrange 2-Factor' , 'activate_plugins', $menu_slug , array( $this, 'mo_wpns'), plugin_dir_url(__FILE__) . 'includes/images/miniorange_icon.png' );
120
- if(get_option('mo_wpns_2fa_with_network_security'))
121
- {
122
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Dashboard' ,'administrator','mo_2fa_dashboard' , array( $this, 'mo_wpns'));
123
- }
124
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Two Factor' ,'administrator','mo_2fa_two_fa' , array( $this, 'mo_wpns'));
125
- if(get_option('mo_wpns_2fa_with_network_security'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  {
127
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Firewall' ,'administrator','mo_2fa_waf' , array( $this, 'mo_wpns'));
128
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Login and Spam' ,'administrator','mo_2fa_login_and_spam' , array( $this, 'mo_wpns'));
129
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Backup' ,'administrator','mo_2fa_backup' , array( $this, 'mo_wpns'));
130
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Malware Scan' ,'administrator','mo_2fa_malwarescan' , array( $this, 'mo_wpns'));
131
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Advanced Blocking' ,'administrator','mo_2fa_advancedblocking' , array( $this, 'mo_wpns'));
132
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Notifications' ,'administrator','mo_2fa_notifications' , array( $this, 'mo_wpns'));
133
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Reports' ,'administrator','mo_2fa_reports' , array( $this, 'mo_wpns'));
134
  }
 
 
 
 
 
135
 
136
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Troubleshooting' ,'administrator','mo_2fa_troubleshooting' , array( $this, 'mo_wpns'));
137
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Account' ,'administrator','mo_2fa_account' , array( $this, 'mo_wpns'));
138
- add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Upgrade' ,'administrator','mo_2fa_upgrade' , array( $this, 'mo_wpns'));
139
- }
140
-
141
- function checkSecurity(){
142
 
143
  $guestcustomer = new Customer_Setup();
144
 
145
  $guestcustomer->guest_audit();
146
  }
147
-
 
148
  function mo_wpns()
149
  {
150
-
151
  global $wpnsDbQueries,$Mo2fdbQueries;
152
  $wpnsDbQueries->mo_plugin_activate();
153
  $Mo2fdbQueries->mo_plugin_activate();
@@ -176,6 +209,7 @@
176
  {
177
  $this->checkSecurity();
178
  global $wpnsDbQueries,$Mo2fdbQueries;
 
179
  $wpnsDbQueries->mo_plugin_activate();
180
  $Mo2fdbQueries->mo_plugin_activate();
181
  add_option( 'mo2f_activate_plugin', 1 );
@@ -194,15 +228,30 @@
194
  add_action( 'mo_auth_show_error_message', array($this, 'mo_auth_show_error_message'), 10, 1 );
195
  add_option( 'mo2f_show_sms_transaction_message', 0 );
196
  add_option( 'mo2f_enforce_strong_passswords_for_accounts' ,'all');
197
- add_option('mo2f_scan_initialize',1);
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  add_option( 'mo_wpns_last_scan_time', time());
 
 
 
 
199
  add_option( 'mo_wpns_2fa_with_network_security' , 1);
200
  add_option( 'mo_wpns_2fa_with_network_security_popup_visible', 1);
201
-
202
-
203
-
204
-
205
 
 
 
206
  }
207
 
208
  function mo_wpns_deactivate()
@@ -217,7 +266,8 @@
217
  delete_option('mo2f_customer_token');
218
  delete_option('mo_wpns_transactionId');
219
  delete_option('mo_wpns_registration_status');
220
- $two_fa_settings = new Miniorange_Authentication();
 
221
  $two_fa_settings->mo_auth_deactivate();
222
  }
223
 
@@ -245,14 +295,62 @@
245
  }
246
  function mo_show_message($content,$type)
247
  {
248
- if($type=="CUSTOM_MESSAGE")
249
- echo $content;
250
- if($type=="NOTICE")
251
- echo ' <div class="is-dismissible notice notice-warning"> <p>'.$content.'</p> </div>';
252
- if($type=="ERROR")
253
- echo ' <div class="notice notice-error is-dismissible"> <p>'.$content.'</p> </div>';
254
- if($type=="SUCCESS")
255
- echo ' <div class="notice notice-success is-dismissible"> <p>'.$content.'</p> </div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  }
257
 
258
  function footer_link()
@@ -270,6 +368,7 @@
270
  require('api/class-customer-setup.php');
271
  require('api/class-rba-attributes.php');
272
  require('api/class-two-factor-setup.php');
 
273
  require('handler/backup.php');
274
  require('handler/security_features.php');
275
  require('handler/feedback_form.php');
@@ -288,16 +387,102 @@
288
  require('helper/constants.php');
289
  require('helper/messages.php');
290
  require('views/common-elements.php');
 
291
  require('controllers/wpns-loginsecurity-ajax.php');
292
  require('controllers/malware_scanner/malware_scan_ajax.php');
293
- require('controllers/backup_ajax.php');
 
294
  require('controllers/dashboard_ajax.php');
295
  require('handler/malware_scanner/malware_scanner_cron.php');
296
  require('handler/malware_scanner/scanner_set_cron.php');
297
-
298
-
299
  }
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  }
302
 
303
  new Miniorange_twoFactor;
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/Authy/LastPass Authenticator, QR Code, Push Notification, Soft Token and Security Questions(KBA) for 1 User in the free version of the plugin.
6
+ * Version: 5.3.24
7
  * Author: miniOrange
8
  * Author URI: https://miniorange.com
9
  * License: GPL2
10
  */
11
+ define( 'MO_HOST_NAME', 'https://login.xecurify.com' );
12
+ define( 'MO2F_VERSION', '5.3.24' );
13
+ define( 'MO2F_TEST_MODE', FALSE );
14
+ define( 'MO2F_IS_ONPREM', get_option('is_onprem'));
15
  class Miniorange_twoFactor{
16
 
17
  function __construct()
23
  add_action( 'admin_enqueue_scripts' , array( $this, 'mo_wpns_settings_script' ) );
24
  add_action( 'wpns_show_message' , array( $this, 'mo_show_message' ), 1 , 2 );
25
  add_action( 'wp_footer' , array( $this, 'footer_link' ),100 );
26
+
27
+ add_action( 'admin_init' , array( $this, 'miniorange_reset_save_settings' ) );
28
+ add_filter('manage_users_columns' , array( $this, 'mo2f_mapped_email_column' ) );
29
+ add_action('manage_users_custom_column' , array( $this, 'mo2f_mapped_email_column_content'), 10, 3 );
30
+
31
+ $actions = add_filter('user_row_actions' , array( $this, 'miniorange_reset_users' ),10 , 2 );
32
+ add_action( 'admin_footer' , array( $this, 'feedback_request' ) );
33
+ add_action('admin_notices',array( $this, 'mo_wpns_malware_notices' ) );
34
  if(get_option('mo2f_disable_file_editing')) define('DISALLOW_FILE_EDIT', true);
35
  $this->includes();
36
  if(get_option("mo_wpns_2fa_with_network_security"))
44
  if ( 'plugins.php' != basename( $_SERVER['PHP_SELF'] ) ) {
45
  return;
46
  }
47
+ global $mo2f_dirName;
48
 
49
  $email = get_option("mo2f_email");
50
  if(empty($email)){
58
  wp_enqueue_script( 'utils' );
59
  wp_enqueue_style( 'mo_wpns_admin_plugins_page_style', plugins_url( '/includes/css/style_settings.css?ver=4.8.60', __FILE__ ) );
60
 
61
+ include $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'feedback_form.php';;
62
 
63
  }
64
  function mo_wpns_malware_notices(){
98
  }else{
99
  $flag_plugin=1;
100
  }
101
+ $one_day = 60*60*24;
102
+ $days =(time()-get_option('mo_wpns_last_scan_time'))/ $one_day;
103
  $days = (int)$days;
104
 
105
+ $day_infected= (time()-get_option('infected_dismiss'))/$one_day;
106
  $day_infected = floor($day_infected);
107
+ $day_weekly= (time()-get_option('weekly_dismiss'))/$one_day;
108
  $day_weekly = floor($day_weekly);
109
 
110
+ if(get_option('mo_wpns_2fa_with_network_security'))
 
111
  {
112
+ if(!get_option('donot_show_infected_file_notice') && (get_option('mo_wpns_infected_files') != 0) && ($day_infected >= 1)){
113
+ echo MoWpnsMessages::showMessage('INFECTED_FILE');
114
+ }else if(!get_option('donot_show_new_plugin_theme_notice') && ($flag_plugin || $flag_theme)){
115
+ echo MoWpnsMessages::showMessage('NEW_PLUGIN_THEME_CHECK');
116
+ }else if(!get_option('donot_show_weekly_scan_notice') && ($days >= 7) && ($day_weekly >= 1)){
117
+ echo MoWpnsMessages::showMessage('WEEKLY_SCAN_CHECK');
118
+ }
119
+ }
120
+ }
 
121
  function mo_wpns_widget_menu()
122
  {
123
+ $user = wp_get_current_user();
124
+ $userID = $user->ID;
125
+ $onprem_admin = get_option('mo2f_onprem_admin');
126
+ $roles = ( array ) $user->roles;
127
+ $flag = 0;
128
+ foreach ( $roles as $role ) {
129
+ if(get_option('mo2fa_'.$role)=='1')
130
+ $flag=1;
131
+ }
132
+
133
+ $is_2fa_enabled=(($flag) or ($userID == $onprem_admin));
134
+
135
+ if( $is_2fa_enabled){
136
+ $menu_slug = 'mo_2fa_two_fa';
137
+ }
138
+ else{
139
+ $menu_slug = 'mo_2fa_dashboard';
140
+ }
141
+ add_menu_page ( 'miniOrange 2-Factor' , 'miniOrange 2-Factor' , 'administrator', $menu_slug , array( $this, 'mo_wpns'), plugin_dir_url(__FILE__) . 'includes/images/miniorange_icon.png' );
142
+ if(get_option('mo_wpns_2fa_with_network_security'))
143
+ {
144
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Dashboard' ,'administrator','mo_2fa_dashboard' , array( $this, 'mo_wpns'),1);
145
+ }
146
+
147
+ if(MO2F_IS_ONPREM)
148
+ {
149
+ if( $is_2fa_enabled){
150
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Two Factor' ,'read', 'mo_2fa_two_fa' , array( $this, 'mo_wpns'),1);
151
+ }
152
+ }
153
+ else{
154
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Two Factor' ,'administrator','mo_2fa_two_fa' , array( $this, 'mo_wpns'),2);
155
+ }
156
+ if(get_option('mo_wpns_2fa_with_network_security'))
157
  {
158
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Firewall' ,'administrator','mo_2fa_waf' , array( $this, 'mo_wpns'),3);
159
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Login and Spam' ,'administrator','mo_2fa_login_and_spam' , array( $this, 'mo_wpns'),4);
160
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Backup' ,'administrator','mo_2fa_backup' , array( $this, 'mo_wpns'),5);
161
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Malware Scan' ,'administrator','mo_2fa_malwarescan' , array( $this, 'mo_wpns'),6);
162
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Advanced Blocking' ,'administrator','mo_2fa_advancedblocking' , array( $this, 'mo_wpns'),7);
163
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Notifications' ,'administrator','mo_2fa_notifications' , array( $this, 'mo_wpns'),8);
164
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Reports' ,'administrator','mo_2fa_reports' , array( $this, 'mo_wpns'),9);
165
  }
166
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Troubleshooting' ,'administrator','mo_2fa_troubleshooting' , array( $this, 'mo_wpns'),10);
167
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Account' ,'administrator','mo_2fa_account' , array( $this, 'mo_wpns'),11);
168
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Upgrade' ,'administrator','mo_2fa_upgrade' , array( $this, 'mo_wpns'),12);
169
+ add_submenu_page( $menu_slug ,'miniOrange 2-Factor' ,'Request for Demo' ,'administrator','mo_2fa_request_demo' , array( $this, 'mo_wpns'),13);
170
+ $mo2fa_hook_page = add_users_page ('Reset 2nd Factor', null , 'manage_options', 'reset', array( $this, 'mo_reset_2fa_for_users_by_admin' ),66);
171
 
172
+
173
+ }
174
+ function checkSecurity(){
 
 
 
175
 
176
  $guestcustomer = new Customer_Setup();
177
 
178
  $guestcustomer->guest_audit();
179
  }
180
+
181
+
182
  function mo_wpns()
183
  {
 
184
  global $wpnsDbQueries,$Mo2fdbQueries;
185
  $wpnsDbQueries->mo_plugin_activate();
186
  $Mo2fdbQueries->mo_plugin_activate();
209
  {
210
  $this->checkSecurity();
211
  global $wpnsDbQueries,$Mo2fdbQueries;
212
+ $userid = wp_get_current_user()->ID;
213
  $wpnsDbQueries->mo_plugin_activate();
214
  $Mo2fdbQueries->mo_plugin_activate();
215
  add_option( 'mo2f_activate_plugin', 1 );
228
  add_action( 'mo_auth_show_error_message', array($this, 'mo_auth_show_error_message'), 10, 1 );
229
  add_option( 'mo2f_show_sms_transaction_message', 0 );
230
  add_option( 'mo2f_enforce_strong_passswords_for_accounts' ,'all');
231
+ add_option('mo2f_onprem_admin' , $userid );
232
+
233
+ update_option('mo_file_backup_plugins',1);
234
+ update_option('mo_file_backup_themes',1);
235
+ update_option('mo_wpns_backup_time',12);
236
+ update_option('file_backup_created',0);
237
+ update_option('db_backup_created',0);
238
+ update_option('scheduled_file_backup',0);
239
+ update_option('scheduled_db_backup',0);
240
+ add_option('file_backup_created_time',0);
241
+ add_option('db_backup_created_time',0);
242
+
243
+ add_option('mo_database_backup',1);
244
+ add_option('mo_wpns_scan_initialize',1);
245
  add_option( 'mo_wpns_last_scan_time', time());
246
+ add_site_option('mo_file_manual_backup_plugins',1);
247
+ add_site_option('mo_file_manual_backup_themes',1);
248
+ add_site_option('mo_schedule_database_backup',1);
249
+
250
  add_option( 'mo_wpns_2fa_with_network_security' , 1);
251
  add_option( 'mo_wpns_2fa_with_network_security_popup_visible', 1);
 
 
 
 
252
 
253
+
254
+ //add_option( 'is_onprem' ,1);
255
  }
256
 
257
  function mo_wpns_deactivate()
266
  delete_option('mo2f_customer_token');
267
  delete_option('mo_wpns_transactionId');
268
  delete_option('mo_wpns_registration_status');
269
+
270
+ $two_fa_settings = new Miniorange_Authentication();
271
  $two_fa_settings->mo_auth_deactivate();
272
  }
273
 
295
  }
296
  function mo_show_message($content,$type)
297
  {
298
+ if($type=="CUSTOM_MESSAGE")
299
+ {
300
+ echo "<div class='overlay_not_JQ_success' id='pop_up_success'><p class='popup_text_not_JQ'>".$content."</p> </div>";
301
+ ?>
302
+ <script type="text/javascript">
303
+ setTimeout(function () {
304
+ var element = document.getElementById("pop_up_success");
305
+ element.classList.toggle("overlay_not_JQ_success");
306
+ element.innerHTML = "";
307
+ }, 4000);
308
+
309
+ </script>
310
+ <?php
311
+ }
312
+ if($type=="NOTICE")
313
+ {
314
+ echo "<div class='overlay_not_JQ_error' id='pop_up_error'><p class='popup_text_not_JQ'>".$content."</p> </div>";
315
+ ?>
316
+ <script type="text/javascript">
317
+ setTimeout(function () {
318
+ var element = document.getElementById("pop_up_error");
319
+ element.classList.toggle("overlay_not_JQ_error");
320
+ element.innerHTML = "";
321
+ }, 4000);
322
+
323
+ </script>
324
+ <?php
325
+ }
326
+ if($type=="ERROR")
327
+ {
328
+ echo "<div class='overlay_not_JQ_error' id='pop_up_error'><p class='popup_text_not_JQ'>".$content."</p> </div>";
329
+ ?>
330
+ <script type="text/javascript">
331
+ setTimeout(function () {
332
+ var element = document.getElementById("pop_up_error");
333
+ element.classList.toggle("overlay_not_JQ_error");
334
+ element.innerHTML = "";
335
+ }, 4000);
336
+
337
+ </script>
338
+ <?php
339
+ }
340
+ if($type=="SUCCESS")
341
+ {
342
+ echo "<div class='overlay_not_JQ_success' id='pop_up_success'><p class='popup_text_not_JQ'>".$content."</p> </div>";
343
+ ?>
344
+ <script type="text/javascript">
345
+ setTimeout(function () {
346
+ var element = document.getElementById("pop_up_success");
347
+ element.classList.toggle("overlay_not_JQ_success");
348
+ element.innerHTML = "";
349
+ }, 4000);
350
+
351
+ </script>
352
+ <?php
353
+ }
354
  }
355
 
356
  function footer_link()
368
  require('api/class-customer-setup.php');
369
  require('api/class-rba-attributes.php');
370
  require('api/class-two-factor-setup.php');
371
+ // require('api/mo2f_api.php');
372
  require('handler/backup.php');
373
  require('handler/security_features.php');
374
  require('handler/feedback_form.php');
387
  require('helper/constants.php');
388
  require('helper/messages.php');
389
  require('views/common-elements.php');
390
+
391
  require('controllers/wpns-loginsecurity-ajax.php');
392
  require('controllers/malware_scanner/malware_scan_ajax.php');
393
+ require('controllers/backup/backup_ajax.php');
394
+ require('controllers/twofa/two_factor_ajax.php');
395
  require('controllers/dashboard_ajax.php');
396
  require('handler/malware_scanner/malware_scanner_cron.php');
397
  require('handler/malware_scanner/scanner_set_cron.php');
 
 
398
  }
399
 
400
+ function miniorange_reset_users($actions, $user_object){
401
+ if ( current_user_can( 'administrator', $user_object->ID ) && get_user_meta($user_object->ID,'currentMethod', true) ) {
402
+ if(get_current_user_id() != $user_object->ID){
403
+ $actions['miniorange_reset_users'] = "<a class='miniorange_reset_users' href='" . admin_url( "users.php?page=reset&action=reset_edit&amp;user=$user_object->ID") . "'>" . __( 'Reset 2 Factor', 'cgc_ub' ) . "</a>";
404
+ }
405
+ }
406
+ return $actions;
407
+
408
+ }
409
+
410
+
411
+ function mo2f_mapped_email_column($columns) {
412
+ $columns['current_method'] = '2FA Method';
413
+ return $columns;
414
+ }
415
+
416
+ function mo_reset_2fa_for_users_by_admin(){
417
+ $nonce = wp_create_nonce('ResetTwoFnonce');
418
+ if(isset($_GET['action']) && $_GET['action']== 'reset_edit'){
419
+ $user_id = $_GET['user'];
420
+ $user_info = get_userdata($user_id);
421
+ ?>
422
+ <form method="post" name="reset2fa" id="reset2fa" action="<?php echo esc_url('users.php'); ?>">
423
+
424
+ <div class="wrap">
425
+ <h1>Reset 2nd Factor</h1>
426
+
427
+ <p>You have specified this user for reset:</p>
428
+
429
+ <ul>
430
+ <li>ID #<?php echo $user_info->ID; ?>: <?php echo $user_info->user_login; ?></li>
431
+ </ul>
432
+ <input type="hidden" name="userid" value="<?php echo $user_id; ?>">
433
+ <input type="hidden" name="miniorange_reset_2fa_option" value="mo_reset_2fa">
434
+ <input type="hidden" name="nonce" value="<?php echo $nonce;?>">
435
+ <p class="submit"><input type="submit" name="submit" id="submit" class="button button-primary" value="Confirm Reset" ></p>
436
+ </div>
437
+ </form>
438
+ <?php
439
+ }
440
+ }
441
+
442
+ function miniorange_reset_save_settings()
443
+ {
444
+ if(isset($_POST['miniorange_reset_2fa_option']) && $_POST['miniorange_reset_2fa_option'] == 'mo_reset_2fa'){
445
+ $nonce = sanitize_text_field($_POST['nonce']);
446
+ if(!wp_verify_nonce($nonce,'ResetTwoFnonce'))
447
+ {
448
+
449
+ return;
450
+ }
451
+ $user_id = isset($_POST['userid']) && !empty($_POST['userid']) ? $_POST['userid'] : '';
452
+ if(!empty($user_id)){
453
+ if ( current_user_can( 'edit_user' ) )
454
+ delete_user_meta($user_id,'currentMethod');
455
+ delete_user_meta($user_id,'mo2f_kba_challenge');
456
+ delete_user_meta($user_id,'mo2f_2FA_method_to_configure');
457
+ delete_user_meta($user_id,'Security Questions');
458
+ delete_user_meta($user_id,'Email Verification');
459
+ delete_user_meta($user_id,'Google Authenticator');
460
+ delete_user_meta($user_id,'kba_questions_user');
461
+ delete_user_meta($user_id,'mo2f_2FA_method_to_test');
462
+ }
463
+ }
464
+ }
465
+
466
+ function mo2f_mapped_email_column_content($value, $column_name, $user_id) {
467
+ if(MO2F_IS_ONPREM)
468
+ {
469
+ $currentMethod = get_user_meta($user_id,'currentMethod', true);
470
+ if(!$currentMethod)
471
+ $currentMethod = 'Not Registered for 2FA';
472
+ }
473
+ else
474
+ {
475
+ global $Mo2fdbQueries;
476
+ $currentMethod = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user_id );
477
+ if(!$currentMethod)
478
+ $currentMethod = 'Not Registered for 2FA';
479
+ }
480
+
481
+ if ( 'current_method' == $column_name )
482
+ return $currentMethod;
483
+ return $value;
484
+ }
485
+
486
  }
487
 
488
  new Miniorange_twoFactor;
readme.txt CHANGED
@@ -6,7 +6,7 @@ Donate link: https://miniorange.com/
6
  Requires at least: 3.0.1
7
  Tested up to: 5.4
8
  Requires PHP: 5.3.0
9
- Stable tag: 5.3.23
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
@@ -272,6 +272,9 @@ miniOrange authentication service has 15+ authentication methods.One time passco
272
 
273
  == Changelog ==
274
 
 
 
 
275
  = 5.3.23 =
276
  * Google Authenticator-Two Factor Authentication (2FA) : Scanner : Timing and caching issue fix.
277
  * Disable 2fa on Woocommerce login.
@@ -735,6 +738,9 @@ More descriptive setup messages and UI changes.
735
 
736
  == Upgrade Notice ==
737
 
 
 
 
738
  = 5.3.23 =
739
  * Google Authenticator-Two Factor Authentication (2FA) : Scanner : Timing and caching issue fix.
740
  * Disable 2fa on Woocommerce login.
6
  Requires at least: 3.0.1
7
  Tested up to: 5.4
8
  Requires PHP: 5.3.0
9
+ Stable tag: 5.3.24
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
 
272
 
273
  == Changelog ==
274
 
275
+ = 5.3.24 =
276
+ * Google Authenticator-Two Factor Authentication (2FA) : On-premise two factor released with multiple users support for some authentication methods.
277
+
278
  = 5.3.23 =
279
  * Google Authenticator-Two Factor Authentication (2FA) : Scanner : Timing and caching issue fix.
280
  * Disable 2fa on Woocommerce login.
738
 
739
  == Upgrade Notice ==
740
 
741
+ = 5.3.24 =
742
+ * Google Authenticator-Two Factor Authentication (2FA) : On-premise two factor released with multiple user support for some authentication methods.
743
+
744
  = 5.3.23 =
745
  * Google Authenticator-Two Factor Authentication (2FA) : Scanner : Timing and caching issue fix.
746
  * Disable 2fa on Woocommerce login.
uninstall.php CHANGED
@@ -42,13 +42,16 @@
42
  delete_option( 'mo_wpns_enable_comment_spam_blocking');
43
  delete_option( 'mo_wpns_enable_comment_recaptcha');
44
 
 
 
 
45
  delete_option( 'mo_wpns_slow_down_attacks');
46
  delete_option( 'mo2f_enforce_strong_passswords');
47
  delete_option( 'mo2f_enforce_strong_passswords_for_accounts');
48
 
49
  delete_option( 'mo_wpns_enable_2fa');
50
  delete_option( 'mo2f_activate_plugin');
51
- delete_option( 'mo_wpns_risk_based_access');
52
  delete_option( 'mo2f_deviceid_enabled');
53
  delete_option( 'mo_wpns_activate_recaptcha');
54
 
@@ -79,24 +82,51 @@
79
 
80
  delete_option('mo_wpns_dbversion');
81
 
82
- delete_option('mo2f_cron_hours');
83
- delete_option('mo2f_enable_cron_backup');
84
- delete_option('mo2f_cron_file_backup_hours');
85
- delete_option('mo2f_enable_cron_file_backup');
86
  delete_option('mo_file_backup_plugins');
87
  delete_option('mo_file_backup_themes');
88
  delete_option('mo_file_backup_wp_files');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
- delete_site_option('mo2f_visit_waf');
91
  delete_site_option('mo2f_visit_login_and_spam');
92
  delete_site_option('mo2f_visit_malware');
93
  delete_site_option('mo2f_visit_backup');
94
  delete_site_option('mo2f_two_factor');
95
- delete_option('mo2f_scan_initialize');
 
 
96
 
97
- delete_option('mo_wpns_2fa_with_network_security');
98
- delete_option('mo_wpns_2fa_with_network_security_popup_visible');
99
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
  $users = get_users( array() );
102
  foreach ( $users as $user ) {
@@ -121,7 +151,6 @@
121
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_malware_scan_report_details" );
122
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_malware_skip_files" );
123
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_malware_hash_file" );
124
- $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_files_scan" );
125
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_attack_logs" );
126
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_ip_rate_details" );
127
 
@@ -348,19 +377,4 @@
348
  delete_option( 'donot_show_infected_file_notice');
349
  delete_option( 'donot_show_new_plugin_theme_notice');
350
  delete_option( 'donot_show_weekly_scan_notice');
351
- delete_option( 'mo_wpns_warning_files');
352
- //delete_option( 'wordpress_download_status');
353
- delete_option( 'mo2f_custom_scan_config');
354
- delete_option( 'mo2f_report_id');
355
- delete_option( 'mo_stop_scan');
356
- delete_option( 'mo2f_repo_status');
357
- delete_option( 'mo2f_scanverification');
358
- delete_option( 'mo2f_repo_path');
359
- delete_option( 'mo2f_download_done');
360
- delete_option( 'downloaded_wordpress_repo_name');
361
- delete_option( 'mo_wpns_scan_status');
362
- delete_option( 'mo_wpns_hide_malware_popup');
363
- delete_option( 'mo_wpns_scan_configuration');
364
- delete_site_option('mo2f_woocommerce_login_prompt');
365
-
366
  ?>
42
  delete_option( 'mo_wpns_enable_comment_spam_blocking');
43
  delete_option( 'mo_wpns_enable_comment_recaptcha');
44
 
45
+ delete_option('mo_wpns_2fa_with_network_security');
46
+ delete_option('mo_wpns_2fa_with_network_security_popup_visible');
47
+
48
  delete_option( 'mo_wpns_slow_down_attacks');
49
  delete_option( 'mo2f_enforce_strong_passswords');
50
  delete_option( 'mo2f_enforce_strong_passswords_for_accounts');
51
 
52
  delete_option( 'mo_wpns_enable_2fa');
53
  delete_option( 'mo2f_activate_plugin');
54
+
55
  delete_option( 'mo2f_deviceid_enabled');
56
  delete_option( 'mo_wpns_activate_recaptcha');
57
 
82
 
83
  delete_option('mo_wpns_dbversion');
84
 
85
+
 
 
 
86
  delete_option('mo_file_backup_plugins');
87
  delete_option('mo_file_backup_themes');
88
  delete_option('mo_file_backup_wp_files');
89
+ delete_option('mo2f_cron_file_backup_hours');
90
+ delete_option('mo2f_cron_hours');
91
+ delete_option('file_backup_created');
92
+ delete_option('db_backup_created');
93
+ delete_option('scheduled_file_backup');
94
+ delete_option('scheduled_db_backup');
95
+ delete_option('file_backup_created_time');
96
+ delete_option('db_backup_created_time');
97
+
98
+ delete_option('mo_database_backup');
99
+ delete_option('mo_wpns_backup_time');
100
+ delete_option('enable_backup_schedule');
101
+ delete_option('mo_wpns_dbversion');
102
+ delete_option('backup_created_time');
103
 
104
+ delete_site_option('mo2f_visit_waf');
105
  delete_site_option('mo2f_visit_login_and_spam');
106
  delete_site_option('mo2f_visit_malware');
107
  delete_site_option('mo2f_visit_backup');
108
  delete_site_option('mo2f_two_factor');
109
+ delete_site_option('mo_file_manual_backup_plugins');
110
+ delete_site_option('mo_file_manual_backup_themes');
111
+ delete_site_option('mo_schedule_database_backup');
112
 
113
+ if(MO2F_IS_ONPREM)
114
+ {
115
+ $users = get_users( array() );
116
+ foreach ( $users as $user ) {
117
+ delete_user_meta( $user->ID, 'currentMethod' );
118
+ delete_user_meta( $user->ID, 'email' );
119
+ delete_user_meta( $user->ID, 'mo2f_2FA_method_to_configure');
120
+ delete_user_meta( $user->ID, 'Security Questions');
121
+ delete_user_meta( $user->ID, 'Email Verification');
122
+ delete_user_meta( $user->ID, 'mo2f_kba_challenge');
123
+ delete_user_meta( $user->ID, 'mo2f_2FA_method_to_test');
124
+ delete_user_meta( $user->ID, 'kba_questions_user');
125
+ delete_user_meta( $user->ID, 'Google Authenticator');
126
+ delete_user_meta( $user->ID, 'mo2f_gauth_key');
127
+ delete_user_meta( $user->ID, 'mo2f_get_auth_rnd_string');
128
+ }
129
+ }
130
 
131
  $users = get_users( array() );
132
  foreach ( $users as $user ) {
151
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_malware_scan_report_details" );
152
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_malware_skip_files" );
153
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_malware_hash_file" );
 
154
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_attack_logs" );
155
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}wpns_ip_rate_details" );
156
 
377
  delete_option( 'donot_show_infected_file_notice');
378
  delete_option( 'donot_show_new_plugin_theme_notice');
379
  delete_option( 'donot_show_weekly_scan_notice');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
  ?>
views/account/register.php CHANGED
@@ -54,4 +54,4 @@ echo'<!--Register with miniOrange-->
54
 
55
 
56
 
57
- </script>
54
 
55
 
56
 
57
+ </script>
views/advanced-blocking.php CHANGED
@@ -1,5 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  echo'<div class="mo_wpns_divided_layout">
4
  <div class="mo_wpns_setting_layout">';
5
 
@@ -7,15 +103,35 @@ echo' <h2>IP Address Range Blocking</h2>
7
  You can block range of IP addresses here ( Examples: 192.168.0.100 - 192.168.0.190 )
8
  <form name="f" method="post" action="" id="iprangeblockingform" >
9
  <input type="hidden" name="option" value="mo_wpns_block_ip_range" />
10
- <table id="iprangeblockingtable">';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
- for($i = 1 ; $i <= $range_count ; $i++)
13
- echo' <tr><td style="width:300px"><input style="padding:0px 10px" class="mo_wpns_table_textbox" type="text" name="range_'.$i.'"
14
  value="'.get_option("mo_wpns_iprange_range_".$i).'" placeholder=" e.g 192.168.0.100 - 192.168.0.190" /></td></tr>';
 
 
15
 
16
- echo' </table>
17
- <a style="cursor:pointer" id="add_range">Add More Range</a><br><br>
18
- <input type="submit" class="mo_wpns_button mo_wpns_button1" value="Block IP range" />
 
 
19
  </form>
20
  </div>
21
 
@@ -105,6 +221,7 @@ echo' </table><br>
105
  </form>
106
  </div>
107
  </div>
 
108
  <script>
109
  jQuery( document ).ready(function() {
110
  var countrycodes = "'.$codes.'";
@@ -118,10 +235,21 @@ echo' </table><br>
118
  var last_index_name = $("#iprangeblockingtable tr:last .mo_wpns_table_textbox").attr("name");
119
  var splittedArray = last_index_name.split("_");
120
  var last_index = parseInt(splittedArray[splittedArray.length-1])+1;
121
- var new_row = \'<tr><td><input style="padding:0px 10px" class="mo_wpns_table_textbox" type="text" name="range_\'+last_index+\'" value="" placeholder=" e.g 192.168.0.100 - 192.168.0.190" /></td></tr>\';
 
122
  $("#iprangeblockingtable tr:last").after(new_row);
123
  });
124
 
 
 
 
 
 
 
 
 
 
 
125
  $("#add_referer").click(function() {
126
  var last_index_name = $("#referrerblockingtable tr:last .mo_wpns_table_textbox").attr("name");
127
  var splittedArray = last_index_name.split("_");
@@ -131,4 +259,285 @@ echo' </table><br>
131
  });
132
 
133
  });
134
- </script>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="wpns_message" style=" padding-top:8px"></div>
2
+ <div class="mo_wpns_divided_layout_tab">
3
+ <div class="mo_wpns_tab">
4
+ <button class="tablinks" onclick="block_function(event, 'block_list')" id="defaultOpen">IP Black list</button>
5
+ <button class="tablinks" onclick="block_function(event, 'adv_block')" id="adv_block_subtab">Advanced Blocking</button>
6
+
7
+ </div>
8
+ </div>
9
+
10
+
11
+ <div id="block_list" class="tabcontent">
12
+
13
+ <div class="mo_wpns_divided_layout">
14
+ <div class="mo_wpns_setting_layout">
15
+ <h2>Manual IP Blocking</h2>
16
+
17
+ <h4 class="mo_wpns_setting_layout_inside">Manually block an IP address here:&emsp;&emsp;
18
+ <input type="text" name="ManuallyBlockIP" id="ManuallyBlockIP" required placeholder='IP address'pattern="((^|\.)((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]?\d))){4}" style="width: 35%; height: 41px" />&emsp;&emsp;
19
+ <input type="button" name="BlockIP" id="BlockIP" value="Manual Block IP" class="mo_wpsn_button mo_wpsn_button1" />
20
+ </h4>
21
+
22
+ <h3 class="mo_wpns_setting_layout_inside"><b>Blocked IP's</b>
23
+ </h3>
24
+ <h4 class="mo_wpns_setting_layout_inside">&emsp;&emsp;&emsp;
25
+
26
+ <div id="blockIPtable">
27
+ <table id="blockedips_table" class="display">
28
+ <thead><tr><th>IP Address&emsp;&emsp;</th><th>Reason&emsp;&emsp;</th><th>Blocked Until&emsp;&emsp;</th><th>Blocked Date&emsp;&emsp;</th><th>Action&emsp;&emsp;</th></tr></thead>
29
+ <tbody>
30
+
31
+ <?php
32
+ $mo_wpns_handler = new MoWpnsHandler();
33
+ $blockedips = $mo_wpns_handler->get_blocked_ips();
34
+ $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
35
+ $disabled = '';
36
+ global $mo2f_dirName;
37
+ foreach($blockedips as $blockedip)
38
+ {
39
+ echo "<tr class='mo_wpns_not_bold'><td>".$blockedip->ip_address."</td><td>".$blockedip->reason."</td><td>";
40
+ if(empty($blockedip->blocked_for_time))
41
+ echo "<span class=redtext>Permanently</span>";
42
+ else
43
+ echo date("M j, Y, g:i:s a",$blockedip->blocked_for_time);
44
+ echo "</td><td>".date("M j, Y, g:i:s a",$blockedip->created_timestamp)."</td><td><a ".$disabled." onclick=unblockip('".$blockedip->id."')>Unblock IP</a></td></tr>";
45
+ }
46
+ ?>
47
+ </tbody>
48
+ </table>
49
+ </div>
50
+ </h4>
51
+ </div>
52
+ <div class="mo_wpns_setting_layout">
53
+ <h2>IP Whitelisting</h2>
54
+ <h4 class="mo_wpns_setting_layout_inside">Add new IP address to whitelist:&emsp;&emsp;
55
+ <input type="text" name="IPWhitelist" id="IPWhitelist" required placeholder='IP address'pattern="((^|\.)((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]?\d))){4}" style="width: 40%; height: 41px"/>&emsp;&emsp;
56
+ <input type="button" name="WhiteListIP" id="WhiteListIP" value="Whitelist IP" class="mo_wpsn_button mo_wpsn_button1" />
57
+
58
+ </h4>
59
+ <h3 class="mo_wpns_setting_layout_inside">Whitelist IP's
60
+ </h3>
61
+ <h4 class="mo_wpns_setting_layout_inside">&emsp;&emsp;&emsp;
62
+
63
+ <div id="WhiteListIPtable">
64
+ <table id="whitelistedips_table" class="display">
65
+ <thead><tr><th>IP Address</th><th>Whitelisted Date</th><th>Remove from Whitelist</th></tr></thead>
66
+ <tbody>
67
  <?php
68
+ foreach($whitelisted_ips as $whitelisted_ip)
69
+ {
70
+ echo "<tr class='mo_wpns_not_bold'><td>".$whitelisted_ip->ip_address."</td><td>".date("M j, Y, g:i:s a",$whitelisted_ip->created_timestamp)."</td><td><a ".$disabled." onclick=removefromwhitelist('".$whitelisted_ip->id."')>Remove</a></td></tr>";
71
+ }
72
+
73
+ echo' </tbody>
74
+ </table>';
75
+ ?>
76
+ </div>
77
+ </h4>
78
+ </div>
79
+
80
+
81
 
82
+ <div class="mo_wpns_setting_layout">
83
+ <h2>IP LookUp</h2>
84
+ <h4 class="mo_wpns_setting_layout_inside">Enter IP address you Want to check:&emsp;&emsp;
85
+ <input type="text" name="ipAddresslookup" id="ipAddresslookup" required placeholder='IP address'pattern="((^|\.)((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]?\d))){4}" style="width: 40%; height: 41px"/>&emsp;&emsp;
86
+ <input type="button" name="LookupIP" id="LookupIP" value="LookUp IP" class="mo_wpsn_button mo_wpsn_button1" />
87
+ </h4>
88
+ <div class="ip_lookup_desc" hidden ></div>
89
+
90
+ <div id="resultsIPLookup">
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </div>
95
+
96
+
97
+ <?php
98
+ echo '<div id="adv_block" class="tabcontent">';
99
  echo'<div class="mo_wpns_divided_layout">
100
  <div class="mo_wpns_setting_layout">';
101
 
103
  You can block range of IP addresses here ( Examples: 192.168.0.100 - 192.168.0.190 )
104
  <form name="f" method="post" action="" id="iprangeblockingform" >
105
  <input type="hidden" name="option" value="mo_wpns_block_ip_range" />
106
+
107
+ <br>
108
+ <table id="iprangetable">
109
+ ';
110
+ for($i = 1 ; $i <= $range_count ; $i++)
111
+ {
112
+ echo '<tr><td>Start IP <input style="width :30%" type ="text" class="mo_wpns_table_textbox" name="start_'.$i.'" value ="'.$start[$i].'" placeholder=" e.g 192.168.0.100" />End IP <input style="width :30%" type ="text" placeholder=" e.g 192.168.0.190" class="mo_wpns_table_textbox" value="'.$end[$i].'" name="end_'.$i.'"/></td></tr>';
113
+ }
114
+ echo '
115
+ </table>
116
+ <a style="cursor:pointer" id="add_ran">Add IP Range</a>
117
+ ';
118
+
119
+ /*echo '
120
+
121
+
122
+ <table id="iprangeblockingtable">';*/
123
 
124
+ //for($i = 1 ; $i <= $range_count ; $i++){
125
+ /*echo' <tr><td style="width:300px"><input style="padding:0px 10px" class="mo_wpns_table_textbox" type="text" name="range_'.$i.'"
126
  value="'.get_option("mo_wpns_iprange_range_".$i).'" placeholder=" e.g 192.168.0.100 - 192.168.0.190" /></td></tr>';
127
+ */
128
+ //}
129
 
130
+ /*echo' </table>
131
+ <a style="cursor:pointer" id="add_range">Add More Range</a> <br><br>
132
+ ';*/
133
+ echo' <br><input type="submit" class="mo_wpns_button mo_wpns_button1" value="Block IP range" />
134
+
135
  </form>
136
  </div>
137
 
221
  </form>
222
  </div>
223
  </div>
224
+ </div>
225
  <script>
226
  jQuery( document ).ready(function() {
227
  var countrycodes = "'.$codes.'";
235
  var last_index_name = $("#iprangeblockingtable tr:last .mo_wpns_table_textbox").attr("name");
236
  var splittedArray = last_index_name.split("_");
237
  var last_index = parseInt(splittedArray[splittedArray.length-1])+1;
238
+
239
+ var new_row = \'<tr><td><input style="padding:0px 10px" class="mo_wpns_table_textbox" type="text" name="range_\'+last_index+\'" value="" placeholder=" e.g 192.168.0.100 - 192.168.0.190" /></td></tr>\';
240
  $("#iprangeblockingtable tr:last").after(new_row);
241
  });
242
 
243
+ $("#add_ran").click(function() {
244
+ var last_index_name = $("#iprangetable tr:last .mo_wpns_table_textbox").attr("name");
245
+
246
+ var splittedArray = last_index_name.split("_");
247
+ var last_index = parseInt(splittedArray[splittedArray.length-1])+1;
248
+ var new_row = \'<tr><td>Start IP<input style="width :30%" type ="text" class="mo_wpns_table_textbox" name="start_\'+last_index+\'" value="" placeholder=" e.g 192.168.0.100" >&nbsp;&nbsp;End IP <input style="width :30%" type ="text" placeholder=" e.g 192.168.0.190" class="mo_wpns_table_textbox" value="" name="end_\'+last_index+\'"></td></tr>\';
249
+ $("#iprangetable tr:last").after(new_row);
250
+
251
+ });
252
+
253
  $("#add_referer").click(function() {
254
  var last_index_name = $("#referrerblockingtable tr:last .mo_wpns_table_textbox").attr("name");
255
  var splittedArray = last_index_name.split("_");
259
  });
260
 
261
  });
262
+ </script>';
263
+
264
+ ?>
265
+ <script type="text/javascript">
266
+ jQuery('#resultsIPLookup').empty();
267
+ function block_function(evt, cityName) {
268
+ var i, tabcontent, tablinks;
269
+ tabcontent = document.getElementsByClassName("tabcontent");
270
+ for (i = 0; i < tabcontent.length; i++) {
271
+ tabcontent[i].style.display = "none";
272
+ }
273
+ tablinks = document.getElementsByClassName("tablinks");
274
+ for (i = 0; i < tablinks.length; i++) {
275
+ tablinks[i].className = tablinks[i].className.replace(" active", "");
276
+ }
277
+
278
+ localStorage.setItem("lastTabadv",cityName);
279
+ evt.currentTarget.className += " active";
280
+
281
+ if(cityName == "defaultOpen")
282
+ {
283
+ jQuery("#defaultOpen").addClass(" active");
284
+ }
285
+ document.getElementById(cityName).style.display = "block";
286
+
287
+ }
288
+
289
+ var tab = localStorage.getItem("lastTabadv");
290
+
291
+ if(tab == "block_list")
292
+ {
293
+ document.getElementById("block_list").style.display = "block";
294
+ document.getElementById("adv_block").style.display = "none";
295
+ jQuery("#defaultOpen").addClass(" active");
296
+
297
+ }
298
+ else if(tab == "adv_block")
299
+ {
300
+ document.getElementById("adv_block").style.display = "block";
301
+ document.getElementById("block_list").style.display = "none";
302
+ jQuery("#adv_block_subtab").addClass(" active");
303
+ }
304
+ else
305
+ {
306
+ document.getElementById("defaultOpen").click();
307
+ jQuery("#defaultOpen").addClass(" active");
308
+ }
309
+
310
+ jQuery('#BlockIP').click(function(){
311
+
312
+ var ip = jQuery('#ManuallyBlockIP').val();
313
+
314
+ var nonce = '<?php echo wp_create_nonce("manualIPBlockingNonce");?>';
315
+ if(ip != '')
316
+ {
317
+ var data = {
318
+ 'action' : 'wpns_login_security',
319
+ 'wpns_loginsecurity_ajax' : 'wpns_ManualIPBlock_form',
320
+ 'IP' : ip,
321
+ 'nonce' : nonce,
322
+ 'option' : 'mo_wpns_manual_block_ip'
323
+ };
324
+ jQuery.post(ajaxurl, data, function(response) {
325
+ var response = response.replace(/\s+/g,' ').trim();
326
+ if(response == 'empty IP')
327
+ {
328
+ jQuery('#wpns_message').empty();
329
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP can not be blank.</div></div>");
330
+ window.onload = nav_popup();
331
+ }
332
+ else if(response == 'already blocked')
333
+ {
334
+ jQuery('#wpns_message').empty();
335
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP is already blocked.</div></div>");
336
+ window.onload = nav_popup();
337
+ }
338
+ else if(response == "INVALID_IP_FORMAT")
339
+ {
340
+ jQuery('#wpns_message').empty();
341
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP does not match required format.</div></div>");
342
+ window.onload = nav_popup();
343
+
344
+ }
345
+ else if(response == "IP_IN_WHITELISTED")
346
+ {
347
+ jQuery('#wpns_message').empty();
348
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP is whitelisted can not be blocked.</div></div>");
349
+ window.onload = nav_popup();
350
+
351
+ }
352
+ else
353
+ {
354
+ jQuery('#wpns_message').empty();
355
+ refreshblocktable(response);
356
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP Blocked Sucessfully.</div></div>");
357
+ window.onload = nav_popup();
358
+ }
359
+
360
+ });
361
+
362
+ }
363
+
364
+ });
365
+
366
+ jQuery('#WhiteListIP').click(function(){
367
+
368
+ var ip = jQuery('#IPWhitelist').val();
369
+
370
+ var nonce = '<?php echo wp_create_nonce("IPWhiteListingNonce");?>';
371
+ if(ip != '')
372
+ {
373
+ var data = {
374
+ 'action' : 'wpns_login_security',
375
+ 'wpns_loginsecurity_ajax' : 'wpns_WhitelistIP_form',
376
+ 'IP' : ip,
377
+ 'nonce' : nonce,
378
+ 'option' : 'mo_wpns_whitelist_ip'
379
+ };
380
+ jQuery.post(ajaxurl, data, function(response) {
381
+
382
+ var response = response.replace(/\s+/g,' ').trim();
383
+ if(response == 'EMPTY IP')
384
+ {
385
+ jQuery('#wpns_message').empty();
386
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP can not be empty.</div></div>");
387
+ window.onload = nav_popup();
388
+
389
+ }
390
+ else if(response == 'INVALID_IP')
391
+ {
392
+ jQuery('#wpns_message').empty();
393
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP does not match required format.</div></div>");
394
+ window.onload = nav_popup();
395
+
396
+ }
397
+ else if(response == 'IP_ALREADY_WHITELISTED')
398
+ {
399
+ jQuery('#wpns_message').empty();
400
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP is already whitelisted.</div></div>");
401
+ window.onload = nav_popup();
402
+
403
+ }
404
+ else
405
+ {
406
+ jQuery('#wpns_message').empty();
407
+ refreshWhiteListTable(response);
408
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP whitelisted Sucessfully.</div></div>");
409
+ window.onload = nav_popup();
410
+
411
+ }
412
+ });
413
+
414
+ }
415
+
416
+ });
417
+
418
+ jQuery("#blockedips_table").DataTable({
419
+ "order": [[ 3, "desc" ]]
420
+ });
421
+ jQuery("#whitelistedips_table").DataTable({
422
+ "order": [[ 1, "desc" ]]
423
+ });
424
+
425
+ jQuery('#LookupIP').click(function(){
426
+ jQuery('#resultsIPLookup').empty();
427
+ var ipAddress = jQuery('#ipAddresslookup').val();
428
+ var nonce = '<?php echo wp_create_nonce("IPLookUPNonce");?>';
429
+ jQuery("#resultsIPLookup").empty();
430
+ jQuery("#resultsIPLookup").append("<img src='<?php if(isset($img_loader_url))echo $img_loader_url;?>'>");
431
+ jQuery("#resultsIPLookup").slideDown(400);
432
+ var data = {
433
+ 'action' : 'wpns_login_security',
434
+ 'wpns_loginsecurity_ajax' : 'wpns_ip_lookup',
435
+ 'nonce' : nonce,
436
+ 'IP' : ipAddress
437
+ };
438
+ jQuery.post(ajaxurl, data, function(response) {
439
+ if(response == 'INVALID_IP_FORMAT')
440
+ {
441
+ jQuery("#resultsIPLookup").empty();
442
+ jQuery('#wpns_message').empty();
443
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP did not match required format.</div></div>");
444
+ window.onload = nav_popup();
445
+ }
446
+ else if(response == 'INVALID_IP')
447
+ {
448
+ jQuery("#resultsIPLookup").empty();
449
+ jQuery('#wpns_message').empty();
450
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP entered is invalid.</div></div>");
451
+ window.onload = nav_popup();
452
+ }
453
+ else if(response.geoplugin_status == 404)
454
+ {
455
+ jQuery("#resultsIPLookup").empty();
456
+ jQuery('#wpns_message').empty();
457
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP details not found.</div></div>");
458
+ window.onload = nav_popup();
459
+ }
460
+ else if (response.geoplugin_status == 200 ||response.geoplugin_status == 206) {
461
+ jQuery('#resultsIPLookup').empty();
462
+ jQuery('#resultsIPLookup').append(response.ipDetails);
463
+ }
464
+
465
+ });
466
+ });
467
+
468
+ function unblockip(id) {
469
+ var nonce = '<?php echo wp_create_nonce("manualIPBlockingNonce");?>';
470
+ if(id != '')
471
+ {
472
+ var data = {
473
+ 'action' : 'wpns_login_security',
474
+ 'wpns_loginsecurity_ajax' : 'wpns_ManualIPBlock_form',
475
+ 'id' : id,
476
+ 'nonce' : nonce,
477
+ 'option' : 'mo_wpns_unblock_ip'
478
+ };
479
+ jQuery.post(ajaxurl, data, function(response) {
480
+ var response = response.replace(/\s+/g,' ').trim();
481
+ if(response=="UNKNOWN_ERROR")
482
+ {
483
+ jQuery('#wpns_message').empty();
484
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Unknow Error occured while unblocking IP.</div></div>");
485
+ window.onload = nav_popup();
486
+ }
487
+ else
488
+ {
489
+ jQuery('#wpns_message').empty();
490
+ refreshblocktable(response);
491
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP UnBlocked Sucessfully.</div></div>");
492
+ window.onload = nav_popup();
493
+ }
494
+ });
495
+
496
+ }
497
+ }
498
+ function removefromwhitelist(id)
499
+ {
500
+ var nonce = '<?php echo wp_create_nonce("IPWhiteListingNonce");?>';
501
+ if(id != '')
502
+ {
503
+ var data = {
504
+ 'action' : 'wpns_login_security',
505
+ 'wpns_loginsecurity_ajax' : 'wpns_WhitelistIP_form',
506
+ 'id' : id,
507
+ 'nonce' : nonce,
508
+ 'option' : 'mo_wpns_remove_whitelist'
509
+ };
510
+ jQuery.post(ajaxurl, data, function(response) {
511
+ var response = response.replace(/\s+/g,' ').trim();
512
+ if(response == 'UNKNOWN_ERROR')
513
+ {
514
+ jQuery('#wpns_message').empty();
515
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Unknow Error occured while removing IP from Whitelist.</div></div>");
516
+ window.onload = nav_popup();
517
+ }
518
+ else
519
+ {
520
+ jQuery('#wpns_message').empty();
521
+ refreshWhiteListTable(response);
522
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP removed from Whitelist.</div></div>");
523
+ window.onload = nav_popup();
524
+ }
525
+ });
526
+
527
+ }
528
+ }
529
+ function refreshblocktable(html)
530
+ {
531
+ jQuery('#blockIPtable').html(html);
532
+ }
533
+
534
+ function refreshWhiteListTable(html)
535
+ {
536
+
537
+ jQuery('#WhiteListIPtable').html(html);
538
+ }
539
+ function nav_popup() {
540
+ document.getElementById("notice_div").style.width = "40%";
541
+ setTimeout(function(){ $('#notice_div').fadeOut('slow'); }, 3000);
542
+ }
543
+ </script>
views/backup.php DELETED
@@ -1,232 +0,0 @@
1
- <?php
2
- add_action( 'admin_footer', 'backup_save_settings' );
3
- echo '
4
- <div id="wpns_backup_message" style=" padding-top:8px"></div>
5
-
6
- ';
7
- echo'
8
- <div class="mo_wpns_divided_layout">
9
- <div class="mo_wpns_setting_layout">';
10
-
11
- echo' <h3>Manual Database Backup</h3>
12
- <form id="mo_wpns_db_backup" method="post" action="">
13
- <input type="hidden" name="option" value="mo_wpns_db_backup" />
14
- <p>Backup your WordPress database easily with a single click. Your backup will be saved in <b>'.site_url().'/miniorange</b> .</p>
15
- <input type="submit" name="submit" value="Backup Now" class="mo_wpns_button mo_wpns_button1" />
16
- </form>
17
- <div class="db_backup_desc" hidden></div>
18
-
19
- <script>
20
- var message = "'.$message.'";
21
- jQuery(document).ready(function() {
22
- $("#mo_wpns_db_backup").on("submit",function (e){
23
- $(".db_backup_desc").empty();
24
- $(".db_backup_desc").append(message);
25
- $(".db_backup_desc").slideDown(400);
26
- setInterval(function(){ $("#inprogress").fadeOut(700); }, 1000);
27
- setInterval(function(){ $("#inprogress").fadeIn(700); }, 1000);
28
- $.ajax({
29
- url: "'.$page_url.'",
30
- type: "GET",
31
- data: "option=backupDB",
32
- crossDomain: !0,
33
- dataType: "json",
34
- contentType: "application/json; charset=utf-8",
35
- success: function(o) {
36
- $("#dbloader").empty();
37
- var result = JSON.stringify(o);
38
- $("#dbloader").append("'.$message2a.' "+result+" '.$message2b.'");
39
- $(".backupmessage").css("background-color","#1EC11E");
40
- $(".backupmessage h2").empty();
41
- $(".backupmessage h2").append("DATABASE BACKUP COMPLETED");
42
- },
43
- error: function(o, e, n) {}
44
- });
45
- e.preventDefault();
46
- });
47
- } );
48
- </script>';
49
- echo '</div>
50
- <div class="mo_wpns_setting_layout">
51
- <h3>Automatic Database Backup</h3>';?>
52
-
53
- <form id="mo2f_enable_cron_backup_form" method="post" action="" >
54
- <table>
55
-
56
- <input type="hidden" name="option" value="mo2f_enable_cron_backup">
57
-
58
- <tr>
59
- <td>
60
- <input type="checkbox" name="mo2f_enable_cron_backup_timely" value="1"
61
- <?php if(get_option('mo2f_enable_cron_backup')) echo "checked";
62
- ?>
63
- onchange="document.getElementById('mo2f_enable_cron_backup_form').submit();"> Enable automatic DB Backup.
64
- </td>
65
- </tr>
66
- </table>
67
- </form>
68
- <?php if(get_option('mo2f_enable_cron_backup')){
69
- $mo2f_cron_hours = (get_option('mo2f_cron_hours')/3600);
70
- ?>
71
- <form id="mo2f_enable_cron_backup" method="post" action="">
72
- <input type="hidden" name="option" value="mo2f_cron_backup_configuration">
73
- <table class="mo2f_ns_settings_table" style="width:100%;">
74
- <tr>
75
- <td>Backup is created in the folder <b>"<?php echo site_url().'/miniorange';
76
- ?>"</b></td>
77
- </tr>
78
- <tr>
79
- <td style="width:40%">Number of hours after which a backup should be created:
80
- <input class="mo2f_ns_table_textbox" style="width:15%;" type="number" id="mo2f_cron_hours" name="mo2f_cron_hours" required placeholder="12" value="<?php echo $mo2f_cron_hours;?>" min="1"/></td>
81
- <td style="width:25%"></td>
82
- </tr>
83
-
84
- <tr>
85
- <td><br><input type="submit" name="submit" value="Save Settings" class="mo_wpns_button mo_wpns_button1" ></td>
86
- </tr>
87
- </table>
88
- </form>
89
- <?php }?>
90
-
91
-
92
-
93
- <?php
94
- echo '</div>
95
- <div class="mo_wpns_setting_layout">
96
- <h3>Files Backup </h3>';?>
97
- <form id="mo2f_enable_cron_file_backup_form" method="post" action="" >
98
- <table>
99
- <tr>
100
- <td><input type="hidden" name="option" value="mo2f_enable_cron_file_backup"></td>
101
- </tr>
102
- <tr>
103
- <td><input type="checkbox" name="mo2f_enable_cron_file_backup_timely" value="1" <?php if(get_option('mo2f_enable_cron_file_backup')) echo "checked";?> onchange="document.getElementById('mo2f_enable_cron_file_backup_form').submit();"> Tick the checkbox if you want take <b>sheduled backup</b> and <b>Save Setting</b> for enable, otherwise create backup manually</td>
104
- </tr>
105
- <tr><td></td></tr>
106
- </table>
107
- </form>
108
- <?php if(get_option('mo2f_enable_cron_file_backup')){
109
- $mo2f_cron_file_backup_hours = get_option('mo2f_cron_file_backup_hours')/3600;
110
- }?>
111
-
112
-
113
- <form id="" method="post" action="">
114
- <input type="hidden" name="option" value="mo_wpns_filebackup_configuration">
115
- <table class="mo2f_ns_settings_table" style="width:100%;">
116
-
117
- <?php if(get_option('mo2f_enable_cron_file_backup')){ ?>
118
-
119
- <tr>
120
- <td style="width:40%">Number of hours after which a backup should be created:
121
- <input class="mo2f_ns_table_textbox" style="width:7%;" type="number" id="mo2f_cron_file_backup_hours" name="mo2f_cron_file_backup_hours" required placeholder="1" value="<?php echo $mo2f_cron_file_backup_hours;?>" min="1"/></td>
122
-
123
- </tr>
124
-
125
- <?php } ?>
126
- <tr>
127
- <td>Backup created in your computer under <b>"/wordpress/miniorange".</b></td>
128
- </tr>
129
-
130
- </table>
131
- <table class="mo_wpns_settings_table">
132
- <!-- <tr>
133
- <td><input type="checkbox" name="mo2f_zip_file_password" value="1" <?php //if(get_option('mo2f_zip_file_password'))echo "checked";?>> You want to protect your backup file with <b>pasaword</b></td>
134
- </tr> -->
135
- <tr>
136
- <td style="width:30%"><b>Select Folders to Backup : </b></td>
137
- <td>
138
- <input type="checkbox"id="mo_file_backup_plugins" name="mo_file_backup_plugins" value="1" <?php checked(get_option('mo_file_backup_plugins') == 1);?>> WordPress Plugins folder<br>
139
- <input type="checkbox" id="mo_file_backup_themes" name="mo_file_backup_themes" value="1" <?php checked(get_option('mo_file_backup_themes') == 1);?>> WordPress Themes folder<br>
140
- <input type="checkbox" id="mo_file_backup_wp_files" name="mo_file_backup_wp_files" value="1" <?php checked(get_option('mo_file_backup_wp_files') == 1);?>> WordPress files
141
- </td>
142
- </tr>
143
-
144
- </table>
145
- <br>
146
- <input type="button" name="create_backup" id="create_backup" value="<?php if(get_option('mo2f_enable_cron_file_backup'))echo 'Save Settings'; else echo 'Backup Now';?>" class="mo_wpns_button mo_wpns_button1">
147
-
148
- <input type="button" name="instant_backup" id="instant_backup" class="mo_wpns_button mo_wpns_button1" style="<?php if(!get_option('mo2f_enable_cron_file_backup'))echo 'display: none';?>; " value="Instant Backup" >
149
- </form>
150
- <form id="instant_file_backup" method="post" action="">
151
- <input type="hidden" name="option" value="instant_file_backup">
152
- </form>
153
-
154
-
155
- <?php
156
-
157
- function backup_save_settings(){
158
- if ( ('admin.php' != basename( $_SERVER['PHP_SELF'] )) || ($_GET['page'] != 'mo_2fa_backup') ) {
159
- return;
160
- }
161
- ?>
162
- <script>
163
- jQuery(document).ready(function(){
164
- jQuery('#create_backup').click(function(){
165
- var data = {
166
- 'action' : 'mo_wpns_backup_ajax',
167
- 'mo_wpns_backup_ajax_forms' : 'wpns_filebackup_form',
168
-
169
- 'backup_plugin':jQuery('input[name= "mo_file_backup_plugins"]:checked').val(),
170
- 'backup_themes':jQuery('input[name= "mo_file_backup_themes"]:checked').val(),
171
- 'backup_wp_files':jQuery('input[name= "mo_file_backup_wp_files"]:checked').val(),
172
- 'file_backup_hour':jQuery('input[name= "mo2f_cron_file_backup_hours"]:input').val(),
173
- };
174
-
175
- jQuery.post(ajaxurl ,data, function(resposnse){
176
- jQuery("#wpns_backup_message").empty();
177
- jQuery("#wpns_backup_message").hide();
178
- jQuery('#wpns_backup_message').show();
179
- if (resposnse == "folder_error"){
180
- jQuery('#wpns_backup_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Please select at least one folder for backup</div>");
181
- window.scrollTo({ top: 0, behavior: 'smooth' });
182
- }else if(resposnse == "invalid_hours"){
183
- jQuery('#wpns_backup_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Invalid hour</div>");
184
- window.scrollTo({ top: 0, behavior: 'smooth' });
185
- }else if(resposnse == "schedule_backup"){
186
- jQuery('#wpns_backup_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Automatic Backup Scheduled Successfully</div>");
187
- window.scrollTo({ top: 0, behavior: 'smooth' });
188
- }else if(resposnse == "manual_backup"){
189
- jQuery('#wpns_backup_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Backup created Successfully</div>");
190
- window.scrollTo({ top: 0, behavior: 'smooth' });
191
- }
192
-
193
- });
194
-
195
- });
196
- jQuery('#instant_backup').click(function(){
197
- jQuery('input[name="instant_backup"]').attr('disabled', true);
198
- document.getElementById('instant_backup').style.backgroundColor = '#b0d2cf';
199
- var intant_value = {
200
- 'action' : 'mo_wpns_backup_ajax',
201
- 'mo_wpns_backup_ajax_forms' : 'wpns_instant_backup',
202
-
203
- 'backup_plugin':jQuery('input[name= "mo_file_backup_plugins"]:checked').val(),
204
- 'backup_themes':jQuery('input[name= "mo_file_backup_themes"]:checked').val(),
205
- 'backup_wp_files':jQuery('input[name= "mo_file_backup_wp_files"]:checked').val(),
206
-
207
- };
208
- jQuery.post(ajaxurl ,intant_value, function(resposnse){
209
- jQuery('input[name="instant_backup"]').removeAttr('disabled');
210
- document.getElementById('instant_backup').style.backgroundColor = '#20b2aa';
211
- jQuery("#wpns_backup_message").empty();
212
- jQuery("#wpns_backup_message").hide();
213
- jQuery('#wpns_backup_message').show();
214
- if (resposnse == "folder_error"){
215
- jQuery('#wpns_backup_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Please select at least one folder for backup</div>");
216
- window.scrollTo({ top: 0, behavior: 'smooth' });
217
- } else if(resposnse == "success"){
218
- jQuery('#wpns_backup_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Backup Created Successfully</div>");
219
- window.scrollTo({ top: 0, behavior: 'smooth' });
220
- }
221
- });
222
- });
223
- });
224
- </script>
225
- <?php }
226
- ?>
227
-
228
- <?php
229
-
230
-
231
- echo '</div></div>';
232
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
views/backup/backup.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <div class="mo_wpns_tab">
3
+ <button class="tablinks" onclick="openTabbackup(event, 'setting_backup')" id="backup_set">Manual Backup</button>
4
+ <button class="tablinks" onclick="openTabbackup(event, 'schdule_view')" id="schdule">Scheduled Backup</button>
5
+ <button class="tablinks" onclick="openTabbackup(event, 'report_view')" id="report">Report</button>
6
+
7
+ </div>
8
+
9
+ <div id="mo_backup_message" style=" padding-top:8px"></div>
10
+ <div class="tabcontent" id="setting_backup">
11
+ <div class="mo_wpns_divided_layout">
12
+ <table style="width: 100%;">
13
+ <tr>
14
+ <td style="width:100%;vertical-align:top;" id="configurationForm2">
15
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'backup'.DIRECTORY_SEPARATOR.'backup_controller.php'; ?>
16
+ </tr>
17
+ </table>
18
+ </div>
19
+ </div>
20
+ <div class="tabcontent" id="schdule_view">
21
+ <div class="mo_wpns_divided_layout">
22
+ <table style="width: 100%;">
23
+ <tr>
24
+ <td style="width:100%;vertical-align:top;" id="configurationForm3">
25
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'backup'.DIRECTORY_SEPARATOR.'backup_schdule.php'; ?>
26
+ </tr>
27
+ </table>
28
+ </div>
29
+ </div>
30
+ <div class="tabcontent" id="report_view">
31
+ <div class="mo_wpns_divided_layout">
32
+ <table style="width: 100%;">
33
+ <tr>
34
+ <td style="width:100%;vertical-align:top;" id="configurationForm4">
35
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'backup'.DIRECTORY_SEPARATOR.'backup_created_report.php'; ?>
36
+ </tr>
37
+ </table>
38
+ </div>
39
+ </div>
40
+
41
+
42
+
43
+ <script>
44
+ document.getElementById("setting_backup").style.display = "block";
45
+ document.getElementById("schdule_view").style.display = "none";
46
+ document.getElementById("report_view").style.display = "none";
47
+
48
+
49
+ document.getElementById("backup_set").className += " active";
50
+ function openTabbackup(evt, tabname){
51
+ var i, tablinks, tabcontent;
52
+ tabcontent = document.getElementsByClassName("tabcontent");
53
+ for (i = 0; i < tabcontent.length; i++) {
54
+ tabcontent[i].style.display = "none";
55
+ }
56
+ tablinks = document.getElementsByClassName("tablinks");
57
+ for (i = 0; i < tablinks.length; i++) {
58
+ tablinks[i].className = tablinks[i].className.replace(" active", "");
59
+ }
60
+ document.getElementById(tabname).style.display = "block";
61
+ localStorage.setItem("lastTabbackup", tabname);
62
+ evt.currentTarget.className += " active";
63
+ }
64
+ var tab = localStorage.getItem("lastTabbackup");
65
+
66
+ if(tab == "setting_backup"){
67
+ document.getElementById("backup_set").click();
68
+ }
69
+ else if(tab == "schdule_view"){
70
+ document.getElementById("schdule").click();
71
+ }
72
+ else if(tab == "report_view"){
73
+ document.getElementById("report").click();
74
+ }
75
+
76
+ else{
77
+ document.getElementById("backup").click();
78
+ }
79
+ </script>
views/backup/backup_created_report.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ ?>
3
+
4
+
5
+ <div class="mo_wpns_setting_layout" id="backup_report_table">
6
+ <?php if(! isset($_GET['view']))?>
7
+ <h2>Backup Created Report</h2>
8
+
9
+ <hr>
10
+ <div id="backupdata">
11
+ <table id="reports_table" class="display" cellspacing="0" width="100%">
12
+ <thead><tr><th style="text-align:center">Created Time</th><th style="text-align:center">Backup Folders</th><th style="text-align:center">Storage</th><th style="text-align:center">Download</th><th style="text-align:center">Delete</th></tr></thead>
13
+ <tbody>
14
+ <br>
15
+ <?php
16
+ include_once $mo2f_dirName. 'controllers'.DIRECTORY_SEPARATOR.'backup'.DIRECTORY_SEPARATOR.'backup_created_result.php';
17
+ echo showBackupResults();
18
+
19
+ ?></tbody>
20
+ </table>
21
+ </div>
22
+ </div>
23
+
24
+ <?php
25
+ function show_backup_report($file_path,$file_name,$timestamp,$id) {
26
+ $time = date('m/d/Y H:i:s', $timestamp);
27
+ $nonce = wp_create_nonce('mo-wpns-download-nonce');
28
+ echo "<tr><td style=text-align:center>".$time."</td>";
29
+ echo "<td style=text-align:center>".$file_name."</td>";
30
+ echo "<td style=text-align:center>Local</td>";
31
+ echo "<td><form action='' method='POST' enctype='multipart/form-data'>
32
+ <input type='hidden' value='mo_wpns_backup_download' name='option' />
33
+ <input type='hidden' value=".$file_name."/".$id." name='file_name' />
34
+ <input type='hidden' value=".$file_path." name='file_path' />
35
+ <input type='hidden' value=".$nonce." name='download_nonce'/>
36
+ <input type='submit' value='Download' name='download' class='upload btn btn-info btn-xs'>
37
+ </form>
38
+ </td>";
39
+ echo "<td><button type='button' onclick=\"backup_delete(this, '".addslashes($file_path)."','".$file_name."',".$id.")\" name='delete' id='delete' class='btn btn-info btn-xs delete'>Delete</button></td>";
40
+ echo "</tr>";
41
+ } ?>
42
+ <script>
43
+ function backup_delete(elmt, file_path,file_name,id){
44
+
45
+ jQuery(document).ready(function(){
46
+
47
+ if(confirm("Are you sure you want to delete it?"))
48
+ {
49
+ var data={
50
+ 'action':'mo_wpns_backup_redirect',
51
+ 'call_type':'delete_backup',
52
+ 'file_name':file_name,
53
+ 'folder_name':file_path,
54
+ 'id' :id,
55
+ 'nonce' : '<?php echo wp_create_nonce("delete_entry");?>',
56
+
57
+ };
58
+
59
+ jQuery.post(ajaxurl, data, function(response){
60
+
61
+ jQuery("#mo_backup_message").empty();
62
+ if(response=="success"){
63
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; Backup delete successfully.</div></div>");
64
+ window.onload = nav_popup();
65
+
66
+ var row = elmt.parentNode.parentNode;
67
+ row.parentNode.removeChild(row);
68
+ }else if(response ==="notexist"){
69
+ jQuery('#mo_backup_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' > Someone has deleted the backup by going to directory please refreash the page </div>");
70
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Someone has deleted the backup by going to directory please refreash the page</div></div>");
71
+ window.onload = nav_popup();
72
+ }
73
+ });
74
+ }
75
+
76
+ });
77
+
78
+ }
79
+ jQuery("#reports_table").DataTable({
80
+ "order": [[ 1, "desc" ]]
81
+ });
82
+
83
+ function nav_popup() {
84
+ document.getElementById("notice_div").style.width = "40%";
85
+ setTimeout(function(){ jQuery('#notice_div').fadeOut('slow'); }, 3000);
86
+ }
87
+ </script>
views/backup/backup_schdule.php ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ add_action('admin_footer','mo_wpns_schedule_backup');
3
+ // mo_wpns_schedule_setting_layout
4
+ ?>
5
+
6
+
7
+ <div class="mo_wpns_setting_layout">
8
+ <br>
9
+ <table class="mo_wpns_settings_table font_class">
10
+ <tr>
11
+ <th>Scheduled file backup </th>
12
+ <th>Scheduled database backup </th>
13
+ </tr>
14
+ <tr><td>&nbsp;</td><td></td></tr>
15
+ <tr>
16
+
17
+ <td><b>Scheduled Status :</b><?php
18
+ if(get_site_option('scheduled_file_backup')){
19
+ ?><span class="mo_green" >Enabled</span><?php
20
+ } else{
21
+ ?><span class="mo_green">Disabled</span><?php
22
+ }
23
+ ?></td>
24
+ <td><b>Scheduled Status :</b><?php
25
+ if(get_site_option('scheduled_db_backup')){
26
+ ?><span class="mo_green" >Enabled</span><?php
27
+ } else{
28
+ ?><span class="mo_green">Disabled</span>
29
+ <?php }
30
+ ?></td>
31
+
32
+ </tr>
33
+
34
+ <tr>
35
+ <td><b>Last Backup :</b><?php
36
+ if($file_backup_time !== 0) echo $file_backup_time ;
37
+ ?></td>
38
+ <td><b>Last Backup :</b><?php
39
+ if($db_eb_backup_time !== 0) echo $db_eb_backup_time ;
40
+ ?></td>
41
+
42
+ </tr>
43
+ <tr>
44
+ <td><b>Next Backup :</b><?php
45
+ if($file_schedule_status == 0){ echo 'N/A';
46
+ } else{ echo $file_day.' '.$file_date.' '.$file_time ;
47
+ }
48
+ ?></td>
49
+ <td><b>Next Backup :</b>
50
+ <?php if($db_backup_status == 0){ echo 'N/A';
51
+ } else{ echo $db_day.' '.$db_date.' '.$db_time ;
52
+ }
53
+ ?></td>
54
+
55
+ </tr>
56
+ </table>
57
+
58
+ </div>
59
+ <div class="mo_wpns_setting_layout text_size" >
60
+
61
+ <form id="" method="post" action="">
62
+ <br>
63
+ <p class="text_size"><b>To automatically create a backup select the following option and save the settings</b></p>
64
+ <input type="checkbox" name="enable_backup_schedule" id="enable_backup_schedule" value="1"<?php checked(get_site_option('enable_backup_schedule') == 1);?>> Enable Backup Schedule<br><br>
65
+
66
+ <br>
67
+ <p class="text_size"><b>Create a backup after every</b></p>
68
+ <table class="mo_wpns_settings_table " >
69
+ <tr>
70
+ <td>
71
+ <input type="radio" name="backup_time" value="12" id="hours"<?php checked(get_site_option('mo_wpns_backup_time') === '12')?>>12 Hours
72
+ </td>
73
+ <td>
74
+ <input type="radio" name="backup_time" value="24" id="daily"<?php checked(get_site_option('mo_wpns_backup_time') === '24')?>> Day
75
+ </td>
76
+ <td>
77
+ <input type="radio" name="backup_time" value="168" id="weekly"<?php checked(get_site_option('mo_wpns_backup_time') === '168')?>>Week
78
+ </td>
79
+ </tr>
80
+ <tr>
81
+ <td>
82
+ <input type="radio" name="backup_time" value="360" id="fortnight"<?php checked(get_site_option('mo_wpns_backup_time') === '360')?>> Fortnight
83
+ </td>
84
+ <td>
85
+ <input type="radio" name="backup_time" value="720" id="month"<?php checked(get_site_option('mo_wpns_backup_time') === '720')?>> Month
86
+ </td>
87
+ </tr>
88
+ </table>
89
+ <br>
90
+ <p class="text_size"><b>Choose the following folder to backup</b></p>
91
+ <table class="mo_wpns_settings_table ">
92
+ <tr>
93
+ <td>
94
+ <input type="checkbox" name="mo_schedule_file_backup_plugins" id="mo_schedule_plugins" value="1"<?php checked(get_site_option('mo_file_backup_plugins') == 1);?>> WordPress Plugins folder
95
+ </td>
96
+ <td>
97
+ <input type="checkbox" name="mo_schedule_file_backup_themes" id="mo_schedule_themes" value="1"<?php checked(get_site_option('mo_file_backup_themes') == 1);?>> WordPress Themes folder
98
+ </td>
99
+ </tr>
100
+ <tr>
101
+ <td>
102
+ <input type="checkbox" name="mo_schedule_file_backup_wp_files" onclick="check1()" value="1"<?php checked(get_site_option('mo_file_backup_wp_files') == 1);?>> WordPress Files
103
+ </td>
104
+ <td>
105
+ <input type="checkbox" name="mo_schedule_database_backup" id="mo_database_backup" value="1"<?php checked(get_site_option('mo_schedule_database_backup') == 1);?>> Database
106
+
107
+ </td>
108
+ </tr>
109
+ </table>
110
+
111
+
112
+ <br>
113
+ <p class="text_size">After checking the <b>enable backup schedule</b> checkbox, a backup will be created once you click on save setting and another backup will be created automatically after the scheduled time you select.</p>
114
+ <input type = "hidden" id = "wpns_schedule_backup_url" value="<?php echo wp_create_nonce('wpns-schedule-backup') ?>" >
115
+ <input type="button" class="mo_wpns_scan_button" name="save_schedule_settings" id="save_schedule_settings" value ="Save Settings" style="width:120px;" />
116
+
117
+
118
+ </div>
119
+ </form>
120
+
121
+ <?php
122
+ function mo_wpns_schedule_backup(){
123
+ ?><script type="text/javascript">
124
+
125
+ jQuery(document).ready(function(){
126
+ jQuery('#save_schedule_settings').click(function(){
127
+ var data={
128
+ 'action':'mo_wpns_backup_redirect',
129
+ 'call_type':'submit_schedule_settings_form',
130
+ 'backup_plugin':jQuery('input[name= "mo_schedule_file_backup_plugins"]:checked').val(),
131
+ 'backup_themes':jQuery('input[name= "mo_schedule_file_backup_themes"]:checked').val(),
132
+ 'backup_wp_files':jQuery('input[name= "mo_schedule_file_backup_wp_files"]:checked').val(),
133
+ 'database':jQuery('input[name= "mo_schedule_database_backup"]:checked').val(),
134
+ 'backup_time':jQuery('input[name= "backup_time"]:checked').val(),
135
+ 'local_storage':jQuery('input[name= "local_storage"]:checked').val(),
136
+ 'enable_backup_schedule':jQuery('input[name= "enable_backup_schedule"]:checked').val(),
137
+ 'nonce' : jQuery('#wpns_schedule_backup_url').val(),
138
+
139
+ };
140
+
141
+
142
+ jQuery.post(ajaxurl, data, function(response){
143
+
144
+ if (response == "folder_error"){
145
+ jQuery('#mo_backup_message').empty();
146
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Please select at least one folder to backup</div></div>");
147
+ window.onload = nav_popup();
148
+ }
149
+
150
+ else if(response=="success"){
151
+ jQuery('#mo_backup_message').empty();
152
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; Backup Configuration Saved Successfully</div></div>");
153
+ window.onload = nav_popup();
154
+ }
155
+ else if(response=="disable"){
156
+ jQuery('#mo_backup_message').empty();
157
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Automatic Backup Disabled</div></div>");
158
+ jQuery(".add_remove_disable").attr("disabled","disabled");
159
+ window.onload = nav_popup();
160
+
161
+ }else if(response==="invalid_hours"){
162
+ jQuery('#mo_backup_message').empty();
163
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Please select valid hours</div></div>");
164
+ window.onload = nav_popup();
165
+
166
+ }else if(response==="ERROR"){
167
+ jQuery('#mo_backup_message').empty();
168
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; ERROR</div></div>");
169
+ window.onload = nav_popup();
170
+ }
171
+
172
+
173
+ });
174
+
175
+ });
176
+ });
177
+
178
+ function nav_popup() {
179
+ document.getElementById("notice_div").style.width = "40%";
180
+ setTimeout(function(){ jQuery('#notice_div').fadeOut('slow'); }, 3000);
181
+ }
182
+
183
+ function check1() {
184
+ if(jQuery('input[name= "mo_schedule_file_backup_wp_files"]:checked').val()){
185
+ jQuery('input[name="mo_schedule_file_backup_plugins"]').attr('disabled', true);
186
+ jQuery('input[name="mo_schedule_file_backup_themes"]').attr('disabled', true);
187
+ jQuery('#mo_schedule_plugins').prop('checked', false); // Unchecks it
188
+ jQuery('#mo_schedule_themes').prop('checked', false); // Unchecks it
189
+ }else{
190
+ jQuery('input[name="mo_schedule_file_backup_plugins"]').removeAttr('disabled');
191
+ jQuery('input[name="mo_schedule_file_backup_themes"]').removeAttr('disabled');
192
+ }
193
+ }
194
+ if(jQuery('input[name= "mo_schedule_file_backup_wp_files"]:checked').val()){
195
+ jQuery('input[name="mo_schedule_file_backup_themes"]').attr('disabled', true);
196
+ jQuery('input[name="mo_schedule_file_backup_plugins"]').attr('disabled', true);
197
+ jQuery('#mo_schedule_plugins').prop('checked', false); // Unchecks it
198
+ jQuery('#mo_schedule_themes').prop('checked', false); // Unchecks it
199
+ }else{
200
+ jQuery('input[name="mo_schedule_file_backup_plugins"]').removeAttr('disabled');
201
+ jQuery('input[name="mo_schedule_file_backup_themes"]').removeAttr('disabled');
202
+ }
203
+
204
+ </script>
205
+ <?php }
206
+ ?>
views/backup/backup_setting_view.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ add_action('admin_footer','mo_backup_config_page_submit');
3
+ ?>
4
+
5
+
6
+ <div class="mo_wpns_setting_layout">
7
+ <div class="mo_wpns_subheading"></div>
8
+ <br>
9
+ <form id="abc" method="post" action="">
10
+ <input type="hidden" name="option" value="mo_wpns_backup_configuration">
11
+ <table class="mo_wpns_settings_table">
12
+ <tr>
13
+ <td style="width:30%"><b>Select Folders to Backup : </b></td>
14
+ <td>
15
+ <input type="checkbox" name="mo_file_backup_wp_files" onclick="check()" id="mo__manual_file_wp_files"
16
+ value="1"<?php checked(get_site_option('mo_file_manual_backup_wp_files') == 1);?>> WordPress Files<br>
17
+
18
+ <input type="checkbox" name="mo_file_backup_plugins" id="mo_file_manual_backup_plugins" value="1"<?php checked(get_site_option('mo_file_manual_backup_plugins') == 1);?>> WordPress Plugins folder<br>
19
+ <input type="checkbox" name="mo_file_backup_themes" id="mo_file_manual_backup_themes" value="1"<?php checked(get_site_option('mo_file_manual_backup_themes') == 1);?>> WordPress Themes folder<br>
20
+
21
+ <input type="checkbox" name="mo_database_backup" value="1"<?php checked(get_site_option('mo_database_backup') == 1);?>> Database
22
+ </td>
23
+ </tr>
24
+
25
+ <tr><td>&nbsp;</td><td></td></tr>
26
+
27
+ <tr>
28
+ <td style="width: 30%"></td>
29
+ <td>
30
+ <input type = "hidden" id = "wpns_backup_settings_url" value="<?php echo wp_create_nonce('wpns-backup-settings') ?>" >
31
+ <input type="button" name="save_backup_settings" id="save_backup_settings" value ="Take Backup" style="width:120px;" class="mo_wpns_scan_button" />
32
+
33
+ </td>
34
+ </tr>
35
+ </table>
36
+
37
+ </form>
38
+ <div class="file_backup_desc" hidden></div>
39
+ </div>
40
+
41
+ <?php
42
+ function mo_backup_config_page_submit(){
43
+ $img_loader_url = plugins_url('miniorange-2-factor-authentication'.DIRECTORY_SEPARATOR .'includes'.DIRECTORY_SEPARATOR .'images'.DIRECTORY_SEPARATOR .'loader.gif');
44
+ $filemessage = '<div id=\'filebackupmessage\'><h2>DO NOT :</h2><ol><li>Close this browser</li><li>Reload this page</li><li>Click the Stop or Back button.</li></ol><h2>Untill your file backup is completed</h2></div><br/><div class=\'filebackupmessage\'><h2><div id=\'backupinprogress\'> BACKUP IN PROGRESS</div></h2></div><div id=\'fileloader\' ><img src=\"'.$img_loader_url.'\"></div>';
45
+ $filemessage2a = 'Backup is Completed. Check ';
46
+ $filemessage2b = ' file in <b>uploads/miniorangebackup</b> folder.';
47
+ ?>
48
+ <script>
49
+
50
+ jQuery(document).ready(function(){
51
+ jQuery('#save_backup_settings').click(function(){
52
+
53
+ var message = "<?php echo $filemessage; ?>";
54
+ jQuery(".file_backup_desc").empty();
55
+ jQuery(".file_backup_desc").append(message);
56
+ jQuery(".file_backup_desc").slideDown(400);
57
+ setInterval(function(){ jQuery("#backupinprogress").fadeOut(700); }, 1000);
58
+ setInterval(function(){ jQuery("#backupinprogress").fadeIn(700); }, 1000);
59
+ document.getElementById("save_backup_settings").value = "Taking Backup...";
60
+ jQuery('input[name="save_backup_settings"]').attr('disabled', true);
61
+ document.getElementById('save_backup_settings').style.backgroundColor = '#20b2aa';
62
+
63
+ var data={
64
+ 'action':'mo_wpns_backup_redirect',
65
+ 'call_type':'submit_backup_settings_form',
66
+ 'backup_plugin':jQuery('input[name= "mo_file_backup_plugins"]:checked').val(),
67
+ 'backup_themes':jQuery('input[name= "mo_file_backup_themes"]:checked').val(),
68
+ 'backup_wp_files':jQuery('input[name= "mo_file_backup_wp_files"]:checked').val(),
69
+ 'database':jQuery('input[name= "mo_database_backup"]:checked').val(),
70
+ 'nonce' :jQuery('#wpns_backup_settings_url').val(),
71
+ };
72
+
73
+
74
+
75
+
76
+
77
+
78
+ jQuery.post(ajaxurl, data, function(response){
79
+
80
+ jQuery("#mo_backup_message").empty();
81
+ jQuery("#mo_backup_message").hide();
82
+ jQuery('#mo_backup_message').show();
83
+
84
+ if (response == "ERROR"){
85
+ jQuery('#mo_backup_message').empty();
86
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; ERROR</div></div>");
87
+ window.onload = nav_popup();
88
+ window.onload = barfw_response_handler('NONCE_ERROR','Nonce did not match');
89
+
90
+ }else if(response == "not_writable"){
91
+ jQuery('#mo_backup_message').empty();
92
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; We don't have write permission. Please give the permission to create folder in uploads</div></div>");
93
+ window.onload = nav_popup();
94
+ window.onload = barfw_response_handler('We do not have write permission. Please give the permission to create folder in uploads','Permission Denied');
95
+
96
+ }
97
+ else if(response == "folder_error")
98
+ {
99
+ jQuery('#mo_backup_message').empty();
100
+ jQuery('#mo_backup_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp;Please select atleast one file folder from manual backup. </div></div>");
101
+ window.onload = nav_popup();
102
+ window.onload = barfw_response_handler('NO FILES TO BACKUP.PLEASE CHANGE MANUAL SETTINGS','Please select at least one folder to backup');
103
+
104
+ }
105
+ else
106
+ {
107
+ var str = 'Your backup is created and store at this location /uploads/miniorangebackup'
108
+ window.onload = barfw_response_handler('BACKUP COMPLETED', str);
109
+
110
+ }
111
+
112
+
113
+ window.onload = nav_popup();
114
+ });
115
+
116
+
117
+
118
+ });
119
+
120
+ });
121
+ function nav_popup() {
122
+ jQuery("#notice_div").style.width = "40%";
123
+ setTimeout(function(){ jQuery('#notice_div').fadeOut('slow'); }, 3000);
124
+ }
125
+
126
+ function barfw_response_handler(para1, para2){
127
+ jQuery(".filebackupmessage h2").empty();
128
+ jQuery(".filebackupmessage h2").append(para1);
129
+
130
+ jQuery("#fileloader").empty();
131
+
132
+ jQuery("#fileloader").append(para2);
133
+ jQuery(".filebackupmessage").css("background-color","#1EC11E");
134
+
135
+ jQuery('input[name="save_backup_settings"]').removeAttr('disabled');
136
+ document.getElementById('save_backup_settings').style.backgroundColor = '#20b2aa';
137
+ document.getElementById("save_backup_settings").value = "Take Backup";
138
+ }
139
+
140
+ function check() {
141
+ if(jQuery('input[name= "mo_file_backup_wp_files"]:checked').val()){
142
+ jQuery('input[name="mo_file_backup_plugins"]').attr('disabled', true);
143
+ jQuery('input[name="mo_file_backup_themes"]').attr('disabled', true);
144
+ jQuery('#mo_file_manual_backup_plugins').prop('checked', false); // Unchecks it
145
+ jQuery('#mo_file_manual_backup_themes').prop('checked', false); // Unchecks it
146
+ }else{
147
+ jQuery('input[name="mo_file_backup_plugins"]').removeAttr('disabled');
148
+ jQuery('input[name="mo_file_backup_themes"]').removeAttr('disabled');
149
+ }
150
+ }
151
+ if(jQuery('input[name= "mo_file_backup_wp_files"]:checked').val()){
152
+ jQuery('input[name="mo_file_backup_plugins"]').attr('disabled', true);
153
+ jQuery('input[name="mo_file_backup_themes"]').attr('disabled', true);
154
+ jQuery('#mo_file_manual_backup_plugins').prop('checked', false); // Unchecks it
155
+ jQuery('#mo_file_manual_backup_themes').prop('checked', false); // Unchecks it
156
+ }else{
157
+ jQuery('input[name="mo_file_backup_plugins"]').removeAttr('disabled');
158
+ jQuery('input[name="mo_file_backup_themes"]').removeAttr('disabled');
159
+ }
160
+
161
+ </script>
162
+ <?php }?>
views/content-protection.php CHANGED
@@ -6,12 +6,20 @@
6
  echo' <h3>Content Protection</h3>
7
  <form id="mo_wpns_content_protection" method="post" action="">
8
  <input type="hidden" name="option" value="mo_wpns_content_protection">
 
 
 
 
 
9
  <p><input type="checkbox" name="protect_wp_config" '.$protect_wp_config.'> <b>Protect your wp-config.php file</b> &nbsp;&nbsp;<a href="'.$wp_config.'" target="_blank" style="text-decoration:none">( Test it )</a></p>
10
  <p>Your WordPress wp-config.php file contains your information like database username and password and it\'s very important to prevent anyone to access contents of your wp-config.php file.</p>
 
11
  <p><input type="checkbox" name="prevent_directory_browsing" '.$protect_wp_uploads.'> <b>Prevent Directory Browsing</b> &nbsp;&nbsp; <span style="color:green;font-weight:bold;">(Recommended)</span> &nbsp;&nbsp; <a href="'.$wp_uploads.'" target="_blank" style="text-decoration:none">( Test it )</a></p>
12
  <p>Prevent access to user from browsing directory contents like images, pdf\'s and other data from URL e.g. http://website-name.com/wp-content/uploads</p>
 
13
  <p><input type="checkbox" name="disable_file_editing" '.$disable_file_editing.'> <b>Disable File Editing from WP Dashboard (Themes and plugins)</b> &nbsp;&nbsp;<a href="'.$plugin_editor.'" target="_blank" style="text-decoration:none">( Test it )</a></p>
14
  <p>The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files. This is often the first tool an attacker will use if able to login, since it allows code execution.</p>
 
15
  <p><input type="checkbox" name="mo2f_htaccess_file" '.$htaccess_file.'> <b>Protect your .htaccess file</b> &nbsp;&nbsp;<span style="color:green;font-weight:bold;">(Recommended)</span></p>
16
  <p>.htaccess has the ability to control your whole website. It is important to first protect this file from unauthorized users.By enabling this you can restrict access to unauthorized users.</p>
17
 
6
  echo' <h3>Content Protection</h3>
7
  <form id="mo_wpns_content_protection" method="post" action="">
8
  <input type="hidden" name="option" value="mo_wpns_content_protection">
9
+ <p><input type="checkbox" name="restrictAPI" '.$restAPI.'/><b>Restrict Public Access to WP REST API to get usernames of all your users.</b><span style="color:green;font-weight:bold;">&nbsp;&nbsp;(Recommended)</span> &nbsp;&nbsp; <a href="'.$restAPI_link.'" target="_blank" style="text-decoration:none">( Test it )</a></p>
10
+ <p>On this website, the REST API root is <b> '.rest_url().'</b><br>
11
+ This Prevents unauthorized access of usernames of your users by blocking the following API ('.$restAPI_link.') .<br> <b>Note:</b> If you are looking for blocking more WordPress Rest APIs please check out the following plugin - <a href="'.$restApiPlugin.'" target="_blank" style="text-decoration:none">WordPress REST API Authentication</a>
12
+ </p>
13
+ <hr>
14
  <p><input type="checkbox" name="protect_wp_config" '.$protect_wp_config.'> <b>Protect your wp-config.php file</b> &nbsp;&nbsp;<a href="'.$wp_config.'" target="_blank" style="text-decoration:none">( Test it )</a></p>
15
  <p>Your WordPress wp-config.php file contains your information like database username and password and it\'s very important to prevent anyone to access contents of your wp-config.php file.</p>
16
+ <hr>
17
  <p><input type="checkbox" name="prevent_directory_browsing" '.$protect_wp_uploads.'> <b>Prevent Directory Browsing</b> &nbsp;&nbsp; <span style="color:green;font-weight:bold;">(Recommended)</span> &nbsp;&nbsp; <a href="'.$wp_uploads.'" target="_blank" style="text-decoration:none">( Test it )</a></p>
18
  <p>Prevent access to user from browsing directory contents like images, pdf\'s and other data from URL e.g. http://website-name.com/wp-content/uploads</p>
19
+ <hr>
20
  <p><input type="checkbox" name="disable_file_editing" '.$disable_file_editing.'> <b>Disable File Editing from WP Dashboard (Themes and plugins)</b> &nbsp;&nbsp;<a href="'.$plugin_editor.'" target="_blank" style="text-decoration:none">( Test it )</a></p>
21
  <p>The WordPress Dashboard by default allows administrators to edit PHP files, such as plugin and theme files. This is often the first tool an attacker will use if able to login, since it allows code execution.</p>
22
+ <hr>
23
  <p><input type="checkbox" name="mo2f_htaccess_file" '.$htaccess_file.'> <b>Protect your .htaccess file</b> &nbsp;&nbsp;<span style="color:green;font-weight:bold;">(Recommended)</span></p>
24
  <p>.htaccess has the ability to control your whole website. It is important to first protect this file from unauthorized users.By enabling this you can restrict access to unauthorized users.</p>
25
 
views/dashboard.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
- global $moWpnsUtility,$dirName;
3
- include_once $dirName . 'views'.DIRECTORY_SEPARATOR.'navbar.php';
4
  add_action('admin_footer','mo_2fa_dashboard_switch');
5
  $two_fa_toggle = get_site_option("mo2f_toggle");
6
  $two_fa_on= get_site_option("mo_2f_switch_2fa")?"checked":"";
1
  <?php
2
+ global $moWpnsUtility,$mo2f_dirName;
3
+ include_once $mo2f_dirName . 'views'.DIRECTORY_SEPARATOR.'navbar.php';
4
  add_action('admin_footer','mo_2fa_dashboard_switch');
5
  $two_fa_toggle = get_site_option("mo2f_toggle");
6
  $two_fa_on= get_site_option("mo_2f_switch_2fa")?"checked":"";
views/error/403.php DELETED
@@ -1,12 +0,0 @@
1
- <?php
2
-
3
- header('HTTP/1.0 403 Forbidden');
4
-
5
- echo '
6
- <h1>403 Forbidden</h1>
7
- You don\'t have permission to access this website.<br><br>
8
- <hr>';
9
-
10
- do_action('log_403');
11
-
12
- exit();
 
 
 
 
 
 
 
 
 
 
 
 
views/login-security.php CHANGED
@@ -156,7 +156,7 @@ echo' <br>
156
  jQuery(document).ready(function(){
157
  jQuery("#mo_bf_save_button").click(function(){
158
  var data = {
159
- 'action': 'wpns_login_security',
160
  'wpns_loginsecurity_ajax' : 'wpns_bruteforce_form',
161
  'bf_enabled/disabled' : jQuery("#mo_bf_button").is(":checked"),
162
  'allwed_login_attempts' : jQuery("#allwed_login_attempts").val(),
@@ -171,21 +171,19 @@ echo' <br>
171
  jQuery("#wpns_message").hide();
172
  jQuery('#wpns_message').show();
173
  if (response == "empty"){
174
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Please fill out all the fields</div>");
175
- window.scrollTo({ top: 0, behavior: 'smooth' });
176
- }
177
  else if(response == "true"){
178
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px;' >Brute force is enabled and configuration has been saved</div>");
179
- window.scrollTo({ top: 0, behavior: 'smooth'});
180
  }
181
  else if(response == "false"){
182
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Brute force is disabled</div>");
183
- window.scrollTo({ top: 0, behavior: 'smooth' });
184
- }
185
  else if(response == "ERROR" ){
186
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >ERROR</div>");
187
- window.scrollTo({ top: 0, behavior: 'smooth' });
188
-
189
  }
190
  });
191
  });
@@ -214,29 +212,25 @@ echo' <br>
214
  jQuery("#wpns_message").hide();
215
  jQuery('#wpns_message').show();
216
  if (response == "empty"){
217
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Please fill out all the fields</div>");
218
- window.scrollTo({ top: 0, behavior: 'smooth' });
219
- }
220
  else if(response == "true"){
221
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >CAPTCHA is enabled.</div>");
222
  jQuery('#loginURL').empty();
223
  jQuery('#loginURL').hide();
224
  jQuery('#loginURL').show();
225
  jQuery('#loginURL').append(data.input_url);
226
- window.scrollTo({ top: 0, behavior: 'smooth' });
227
- }
228
  else if(response == "false"){
229
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >CAPTCHA is disabled.</div>");
230
  jQuery('#loginURL').empty();
231
  jQuery('#loginURL').hide();
232
  jQuery('#loginURL').show();
233
  jQuery('#loginURL').append('wp-login.php');
234
- window.scrollTo({ top: 0, behavior: 'smooth' });
235
- }
236
  else if(response == "ERROR" ){
237
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >ERROR</div>");
238
- window.scrollTo({ top: 0, behavior: 'smooth' });
239
-
240
  }
241
  });
242
  });
@@ -255,25 +249,27 @@ echo' <br>
255
  jQuery("#wpns_message").hide();
256
  jQuery('#wpns_message').show();
257
  if(response == "true"){
258
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Strong password is enabled.</div>");
259
- window.scrollTo({ top: 0, behavior: 'smooth' });
260
- }
261
  else if(response == "false"){
262
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Strong Password is disabled.</div>");
263
- window.scrollTo({ top: 0, behavior: 'smooth' });
264
- }
265
  else if(response == "ERROR" ){
266
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >ERROR</div>");
267
- window.scrollTo({ top: 0, behavior: 'smooth' });
268
-
269
  }
270
  });
271
  });
272
  });
273
-
 
 
 
 
 
274
  </script>
275
 
276
 
277
  <?php }
278
 
279
-
156
  jQuery(document).ready(function(){
157
  jQuery("#mo_bf_save_button").click(function(){
158
  var data = {
159
+ 'action' : 'wpns_login_security',
160
  'wpns_loginsecurity_ajax' : 'wpns_bruteforce_form',
161
  'bf_enabled/disabled' : jQuery("#mo_bf_button").is(":checked"),
162
  'allwed_login_attempts' : jQuery("#allwed_login_attempts").val(),
171
  jQuery("#wpns_message").hide();
172
  jQuery('#wpns_message').show();
173
  if (response == "empty"){
174
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Please fill out all the fields</div></div>");
175
+ window.onload = nav_popup();
176
+ }
177
  else if(response == "true"){
178
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp;Brute force is enabled and configuration has been saved</div></div>");
179
+ window.onload = nav_popup();
180
  }
181
  else if(response == "false"){
182
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Brute force is disabled</div></div>");
183
+ window.onload = nav_popup(); }
 
184
  else if(response == "ERROR" ){
185
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; ERROR</div></div>");
186
+ window.onload = nav_popup();
 
187
  }
188
  });
189
  });
212
  jQuery("#wpns_message").hide();
213
  jQuery('#wpns_message').show();
214
  if (response == "empty"){
215
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Please fill out all the fields</div></div>");
216
+ window.onload = nav_popup(); }
 
217
  else if(response == "true"){
 
218
  jQuery('#loginURL').empty();
219
  jQuery('#loginURL').hide();
220
  jQuery('#loginURL').show();
221
  jQuery('#loginURL').append(data.input_url);
222
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; CAPTCHA is enabled.</div></div>");
223
+ window.onload = nav_popup(); }
224
  else if(response == "false"){
 
225
  jQuery('#loginURL').empty();
226
  jQuery('#loginURL').hide();
227
  jQuery('#loginURL').show();
228
  jQuery('#loginURL').append('wp-login.php');
229
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; CAPTCHA is disabled.</div></div>");
230
+ window.onload = nav_popup(); }
231
  else if(response == "ERROR" ){
232
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; ERROR</div></div>");
233
+ window.onload = nav_popup();
 
234
  }
235
  });
236
  });
249
  jQuery("#wpns_message").hide();
250
  jQuery('#wpns_message').show();
251
  if(response == "true"){
252
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; Strong password is enabled.</div></div>");
253
+ window.onload = nav_popup(); }
 
254
  else if(response == "false"){
255
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Strong Password is disabled.</div></div>");
256
+ window.onload = nav_popup(); }
 
257
  else if(response == "ERROR" ){
258
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; ERROR</div></div>");
259
+ window.onload = nav_popup();
 
260
  }
261
  });
262
  });
263
  });
264
+
265
+
266
+ function nav_popup() {
267
+ document.getElementById("notice_div").style.width = "40%";
268
+ setTimeout(function(){ $('#notice_div').fadeOut('slow'); }, 3000);
269
+ }
270
  </script>
271
 
272
 
273
  <?php }
274
 
275
+
views/login_spam.php CHANGED
@@ -10,7 +10,7 @@
10
  <table style="width:100%;">
11
  <tr>
12
  <td>
13
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'login-security.php'; ?>
14
  </td>
15
  </tr>
16
  </table>
@@ -21,7 +21,7 @@
21
  <table style="width:100%;">
22
  <tr>
23
  <td>
24
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'registration-security.php'; ?>
25
  </td>
26
  </tr>
27
  </table>
@@ -32,7 +32,7 @@
32
  <table style="width:100%;">
33
  <tr>
34
  <td>
35
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'content-protection.php'; ?>
36
  </td>
37
  </tr>
38
  </table>
10
  <table style="width:100%;">
11
  <tr>
12
  <td>
13
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'login-security.php'; ?>
14
  </td>
15
  </tr>
16
  </table>
21
  <table style="width:100%;">
22
  <tr>
23
  <td>
24
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'registration-security.php'; ?>
25
  </td>
26
  </tr>
27
  </table>
32
  <table style="width:100%;">
33
  <tr>
34
  <td>
35
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'content-protection.php'; ?>
36
  </td>
37
  </tr>
38
  </table>
views/malware_scanner/malware_scan.php CHANGED
@@ -13,14 +13,14 @@
13
  <button class="tablinks" onclick="openTabmalware(event, 'scan_report')" id="report_scan">Scan Reports</button>
14
  <input type = "hidden" id = "wpns_report_nonce" value="<?php echo wp_create_nonce('wpns-report-load') ?>" >
15
  </div>
16
- <br>
17
  <div id="mo_scan_message" style=" padding-top:8px"></div>
18
  <div class="tabcontent" id="scan_view">
19
  <div class="mo_wpns_divided_layout">
20
  <table style="width: 100%;">
21
  <tr>
22
  <td style="width:100%;vertical-align:top;" id="configurationForm">
23
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_malware_summary.php'; ?>
24
  </tr>
25
  </table>
26
  </div>
@@ -30,7 +30,7 @@
30
  <table style="width: 100%;">
31
  <tr>
32
  <td style="width:100%;vertical-align:top;" id="configurationForm">
33
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_malware_settings.php'; ?>
34
  </tr>
35
  </table>
36
  </div>
@@ -40,7 +40,7 @@
40
  <table style="width: 100%;">
41
  <tr>
42
  <td style="width:100%;vertical-align:top;" id="configurationForm">
43
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_malware_report.php'; ?>
44
  </tr>
45
  </table>
46
  </div>
13
  <button class="tablinks" onclick="openTabmalware(event, 'scan_report')" id="report_scan">Scan Reports</button>
14
  <input type = "hidden" id = "wpns_report_nonce" value="<?php echo wp_create_nonce('wpns-report-load') ?>" >
15
  </div>
16
+
17
  <div id="mo_scan_message" style=" padding-top:8px"></div>
18
  <div class="tabcontent" id="scan_view">
19
  <div class="mo_wpns_divided_layout">
20
  <table style="width: 100%;">
21
  <tr>
22
  <td style="width:100%;vertical-align:top;" id="configurationForm">
23
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_malware_summary.php'; ?>
24
  </tr>
25
  </table>
26
  </div>
30
  <table style="width: 100%;">
31
  <tr>
32
  <td style="width:100%;vertical-align:top;" id="configurationForm">
33
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_malware_settings.php'; ?>
34
  </tr>
35
  </table>
36
  </div>
40
  <table style="width: 100%;">
41
  <tr>
42
  <td style="width:100%;vertical-align:top;" id="configurationForm">
43
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'scan_malware_report.php'; ?>
44
  </tr>
45
  </table>
46
  </div>
views/malware_scanner/scan_report_view.php CHANGED
@@ -9,7 +9,7 @@
9
  <hr>
10
  <div id="scandata">
11
  <?php
12
- include_once $dirName. 'controllers'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'malware_scan_result.php';
13
  echo showScanResults();
14
  ?>
15
  </div>
9
  <hr>
10
  <div id="scandata">
11
  <?php
12
+ include_once $mo2f_dirName. 'controllers'.DIRECTORY_SEPARATOR.'malware_scanner'.DIRECTORY_SEPARATOR.'malware_scan_result.php';
13
  echo showScanResults();
14
  ?>
15
  </div>
views/malware_scanner/scan_summary_view.php CHANGED
@@ -1,6 +1,5 @@
1
  <?php
2
  add_action('admin_footer','mo_wpns_start_scan');
3
-
4
  ?>
5
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
6
 
@@ -195,10 +194,8 @@ function mo_wpns_start_scan(){
195
 
196
  }
197
 
198
-
199
- function scan_start_request(scan_type,scanButtonID){
200
  document.getElementById(scanButtonID).value = "Scanning...";
201
-
202
  var scanOption = new Map();
203
 
204
  if(pop_up == false){
@@ -362,9 +359,6 @@ function mo_wpns_start_scan(){
362
  });
363
 
364
 
365
-
366
-
367
-
368
  var scan_modal_confirm = document.getElementById("mo2f_scan_confirm_modal");
369
  window.onclick = function(event) {
370
  if (event.target == scan_modal_confirm) {
@@ -396,8 +390,8 @@ function mo_wpns_start_scan(){
396
  return estimatedTime;
397
 
398
  }
399
- function scan_response_status(scanset,serverResponse){
400
 
 
401
  document.getElementById("progress_message").innerHTML = scanset.get("progress_message");
402
  var bar= document.getElementById("mo_wpns_progress_bar");
403
  bar.style.width= 100 + "%";
@@ -485,7 +479,6 @@ function scan_response_status(scanset,serverResponse){
485
  document.getElementById("progress_message").innerHTML= "Scan in progress. It may take some time...";
486
  bar.innerHTML = width + "%";
487
  }
488
-
489
  }
490
  });
491
  }
@@ -554,4 +547,3 @@ function show_summary(){
554
  <?php
555
  }
556
 
557
-
1
  <?php
2
  add_action('admin_footer','mo_wpns_start_scan');
 
3
  ?>
4
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
5
 
194
 
195
  }
196
 
197
+ function scan_start_request(scan_type,scanButtonID){
 
198
  document.getElementById(scanButtonID).value = "Scanning...";
 
199
  var scanOption = new Map();
200
 
201
  if(pop_up == false){
359
  });
360
 
361
 
 
 
 
362
  var scan_modal_confirm = document.getElementById("mo2f_scan_confirm_modal");
363
  window.onclick = function(event) {
364
  if (event.target == scan_modal_confirm) {
390
  return estimatedTime;
391
 
392
  }
 
393
 
394
+ function scan_response_status(scanset,serverResponse){
395
  document.getElementById("progress_message").innerHTML = scanset.get("progress_message");
396
  var bar= document.getElementById("mo_wpns_progress_bar");
397
  bar.style.width= 100 + "%";
479
  document.getElementById("progress_message").innerHTML= "Scan in progress. It may take some time...";
480
  bar.innerHTML = width + "%";
481
  }
 
482
  }
483
  });
484
  }
547
  <?php
548
  }
549
 
 
views/navbar.php CHANGED
@@ -1,13 +1,21 @@
1
  <?php
 
2
  $security_features_nonce = wp_create_nonce('mo_2fa_security_features_nonce');
3
 
 
 
 
 
 
 
 
 
 
 
4
  if($shw_feedback)
5
- do_action('wpns_show_message',MoWpnsMessages::showMessage('FEEDBACK'),'CUSTOM_MESSAGE');
6
- if(get_option('mo_wpns_2fa_with_network_security'))
7
- {
8
- if(!$safe)
9
- do_action('wpns_show_message',MoWpnsMessages::showMessage('WHITELIST_SELF'),'CUSTOM_MESSAGE');
10
- }
11
  echo'<div class="wrap">
12
  <div><img style="float:left;margin-top:5px;" src="'.$logo_url.'"></div>
13
  <h1>
@@ -48,7 +56,15 @@ echo' <span style="text-align:right;">
48
  {
49
  echo '<a class="nav-tab '.($active_tab == 'mo_2fa_dashboard' ? 'nav-tab-active' : '').'" href="'.$dashboard_url .'">Dashboard</a>';
50
  }
51
- echo '<a class="nav-tab '.($active_tab == 'mo_2fa_two_fa' ? 'nav-tab-active' : '').'" href="'.$two_fa .'">Two Factor</a>';
 
 
 
 
 
 
 
 
52
  if(get_option('mo_wpns_2fa_with_network_security'))
53
  {
54
  if(get_site_option('mo_2f_switch_waf')){
@@ -71,8 +87,9 @@ echo' <span style="text-align:right;">
71
  }
72
  if(get_site_option('mo_2f_switch_reports')){
73
  echo '<a id="report_tab" class="nav-tab '.($active_tab == 'mo_2fa_reports' ? 'nav-tab-active' : '').'" href="'.$reports_url .'">Reports</a>';
74
- }
75
  }
76
  echo '<a class="nav-tab '.($active_tab == 'mo_2fa_upgrade' ? 'nav-tab-active' : '').'" href="'.$upgrade_url .'">Upgrade</a>';
 
77
  ?>
78
- </div>
1
  <?php
2
+
3
  $security_features_nonce = wp_create_nonce('mo_2fa_security_features_nonce');
4
 
5
+ $user = wp_get_current_user();
6
+ $userID = wp_get_current_user()->ID;
7
+ $onprem_admin = get_option('mo2f_onprem_admin');
8
+ $roles = ( array ) $user->roles;
9
+ $is_onprem = MO2F_IS_ONPREM;
10
+ $flag = 0;
11
+ foreach ( $roles as $role ) {
12
+ if(get_option('mo2fa_'.$role)=='1')
13
+ $flag=1;
14
+ }
15
  if($shw_feedback)
16
+ echo MoWpnsMessages::showMessage('FEEDBACK');
17
+ if(!$safe)
18
+ echo MoWpnsMessages::showMessage('WHITELIST_SELF');
 
 
 
19
  echo'<div class="wrap">
20
  <div><img style="float:left;margin-top:5px;" src="'.$logo_url.'"></div>
21
  <h1>
56
  {
57
  echo '<a class="nav-tab '.($active_tab == 'mo_2fa_dashboard' ? 'nav-tab-active' : '').'" href="'.$dashboard_url .'">Dashboard</a>';
58
  }
59
+ if($is_onprem){
60
+ if( ($flag) or ($userID == $onprem_admin) ){
61
+ echo '<a class="nav-tab '.($active_tab == 'mo_2fa_two_fa' ? 'nav-tab-active' : '').'" href="'.$two_fa .'">Two Factor</a>';
62
+ }
63
+ }
64
+ else{
65
+ echo '<a class="nav-tab '.($active_tab == 'mo_2fa_two_fa' ? 'nav-tab-active' : '').'" href="'.$two_fa .'">Two Factor</a>';
66
+ }
67
+
68
  if(get_option('mo_wpns_2fa_with_network_security'))
69
  {
70
  if(get_site_option('mo_2f_switch_waf')){
87
  }
88
  if(get_site_option('mo_2f_switch_reports')){
89
  echo '<a id="report_tab" class="nav-tab '.($active_tab == 'mo_2fa_reports' ? 'nav-tab-active' : '').'" href="'.$reports_url .'">Reports</a>';
90
+ }
91
  }
92
  echo '<a class="nav-tab '.($active_tab == 'mo_2fa_upgrade' ? 'nav-tab-active' : '').'" href="'.$upgrade_url .'">Upgrade</a>';
93
+ echo '<a class="nav-tab '.($active_tab == 'mo_2fa_request_demo' ? 'nav-tab-active' : '').'" href="'.$request_demo_url .'">Request for Demo</a>';
94
  ?>
95
+ </div>
views/rate-limiting.php CHANGED
@@ -108,14 +108,14 @@
108
  jQuery.post(ajaxurl, data, function(response) {
109
  if(response == '')
110
  {
111
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >SQL Injection protection is enabled</div>");
112
- window.scrollTo({ top: 0, behavior: 'smooth' });
113
- }
114
  else
115
  {
116
- jQuery('#wpns_message').append("notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >SQL Injection protection is disabled.</div>");
117
- window.scrollTo({ top: 0, behavior: 'smooth' });
118
- }
119
 
120
  });
121
  }
@@ -142,20 +142,22 @@
142
  jQuery.post(ajaxurl, data, function(response) {
143
  if(response == '')
144
  {
145
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >SQL Injection protection is enabled</div>");
146
- window.scrollTo({ top: 0, behavior: 'smooth' });
147
- }
148
  else
149
  {
150
- jQuery('#wpns_message').append("notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >SQL Injection protection is disabled.</div>");
151
- window.scrollTo({ top: 0, behavior: 'smooth' });
152
- }
153
 
154
  });
155
  }
156
 
157
  });
158
 
 
 
 
 
159
 
160
  </script>
161
 
108
  jQuery.post(ajaxurl, data, function(response) {
109
  if(response == '')
110
  {
111
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; SQL Injection protection is enabled</div></div>");
112
+ window.onload = nav_popup();
113
+ }
114
  else
115
  {
116
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; SQL Injection protection is disabled.</div></div>");
117
+ window.onload = nav_popup();
118
+ }
119
 
120
  });
121
  }
142
  jQuery.post(ajaxurl, data, function(response) {
143
  if(response == '')
144
  {
145
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; SQL Injection protection is enabled/div></div>");
146
+ window.onload = nav_popup(); }
 
147
  else
148
  {
149
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; SQL Injection protection is disabled.</div></div>");
150
+ window.onload = nav_popup(); }
 
151
 
152
  });
153
  }
154
 
155
  });
156
 
157
+ function nav_popup() {
158
+ document.getElementById("notice_div").style.width = "40%";
159
+ setTimeout(function(){ $('#notice_div').fadeOut('slow'); }, 3000);
160
+ }
161
 
162
  </script>
163
 
views/request_demo.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="mo_wpns_divided_layout">
2
+ <div class="mo_wpns_setting_layout">
3
+ <h3> Demo Request Form : </h3>
4
+ <form method="post">
5
+ <input type="hidden" name="option" value="mo_2FA_demo_request_form" />
6
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce('mo2f-Request-demo')?>">
7
+ <table cellpadding="4" cellspacing="4">
8
+ <tr>
9
+ <td><strong>Usecase : </strong></td>
10
+ <td>
11
+ <textarea type="text" minlength="15" name="mo_2FA_demo_usecase" style="resize: vertical; width:350px; height:100px;" rows="4" placeholder="Write us about your usecase" required value=""></textarea>
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <td></td>
16
+
17
+ </tr>
18
+ <tr>
19
+ <td><strong>Email ID : </strong></td>
20
+ <td><input required type="email" name="mo_2FA_demo_email" placeholder="Email id" value="" /></td>
21
+ </tr>
22
+ <tr>
23
+ <td><strong>Request a demo for : </strong></td>
24
+ <td>
25
+ <select required name="mo_2FA_demo_plan" id="mo_2FA_demo_plan_id">
26
+ <option disabled selected>------------------ Select ------------------</option>
27
+ <option value="2FA">Two Factor Authentication</option>
28
+ <option value="WAF">Web Application Firewall (WAF) </option>
29
+ <option value="malwareScanner">Malware Scanner</option>
30
+ <option value="login_spam">Login Security</option>
31
+ <option value="backup">Encrypted Backup </option>
32
+ <option value="notSure">Not Sure/Multiple options</option>
33
+ </select>
34
+ </td>
35
+ </tr>
36
+
37
+ </table>
38
+ <div style="padding-top: 10px;">
39
+ <input type="submit" name="submit" value="Submit Demo Request" class="mo_wpns_button mo_wpns_button1" />
40
+ </div>
41
+ </form>
42
+ </div>
43
+ </div>
views/test/test_twofa_email_verification.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php function mo2f_test_email_verification() { ?>
2
+
3
+ <h3><?php echo mo2f_lt( 'Test Email Verification' ); ?></h3>
4
+ <hr>
5
+ <div>
6
+ <br>
7
+ <br>
8
+ <center>
9
+ <h3><?php echo mo2f_lt( 'A verification email is sent to your registered email.' ); ?>
10
+ <br>
11
+ <?php echo mo2f_lt( 'We are waiting for your approval...' ); ?></h3>
12
+ <img src="<?php echo plugins_url( '/../includes/images/ajax-loader-login.gif', __FILE__ ); ?>"/>
13
+ </center>
14
+
15
+ <input type="button" name="back" id="go_back" class="mo_wpns_button mo_wpns_button1"
16
+ value="<?php echo mo2f_lt( 'Back' ); ?>"
17
+ style="margin-top:100px;margin-left:10px;"/>
18
+ </div>
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>
38
+ jQuery('#go_back').click(function () {
39
+ jQuery('#mo2f_go_back_form').submit();
40
+ });
41
+
42
+ var timeout;
43
+
44
+
45
+
46
+ pollMobileValidation();
47
+ function pollMobileValidation() {
48
+ var transId = "<?php echo $_SESSION['mo2f_transactionId']; ?>";
49
+ var jsonString = "{\"txId\":\"" + transId + "\"}";
50
+ var postUrl = "<?php echo MO_HOST_NAME; ?>" + "/moas/api/auth/auth-status";
51
+
52
+ jQuery.ajax({
53
+ url: postUrl,
54
+ type: "POST",
55
+ dataType: "json",
56
+ data: jsonString,
57
+ contentType: "application/json; charset=utf-8",
58
+ success: function (result) {
59
+ var status = JSON.parse(JSON.stringify(result)).status;
60
+ if (status == 'SUCCESS') {
61
+ jQuery('#mo2f_out_of_band_success_form').submit();
62
+ } else if (status == 'ERROR' || status == 'FAILED' || status == 'DENIED') {
63
+ jQuery('#mo2f_out_of_band_error_form').submit();
64
+ } else {
65
+ timeout = setTimeout(pollMobileValidation, 3000);
66
+ }
67
+ }
68
+ });
69
+ }
70
+
71
+
72
+ </script>
73
+
74
+ <?php }
75
+
76
+ ?>
views/test/test_twofa_google_authy_authenticator.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php function mo2f_test_google_authy_authenticator( $user, $method ) {
2
+
3
+ ?>
4
+ <h3><?php echo mo2f_lt( 'Test ' ) . mo2f_lt( $method ); ?></h3>
5
+ <hr>
6
+ <p><?php echo mo2f_lt( 'Enter the verification code from the configured account in your ' ) . mo2f_lt( $method )
7
+ . mo2f_lt( ' app.' ); ?></p>
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%;"/>
16
+ <br><br>
17
+ <input type="button" name="back" id="go_back" class="mo_wpns_button mo_wpns_button1"
18
+ value="<?php echo mo2f_lt( 'Back' ); ?>"/>
19
+ <input type="submit" name="validate" id="validate" class="mo_wpns_button mo_wpns_button1"
20
+ value="<?php echo mo2f_lt( 'Submit' ); ?>"/>
21
+
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 () {
30
+ jQuery('#mo2f_go_back_form').submit();
31
+ });
32
+ </script>
33
+
34
+ <?php
35
+ } ?>
views/test/test_twofa_kba_questions.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function mo2f_test_kba_security_questions( $user ) {
3
+ ?>
4
+ <h3><?php echo mo2f_lt( 'Test Security Questions( KBA )' ); ?></h3>
5
+ <hr>
6
+ <br>
7
+
8
+
9
+ <form name="f" method="post" action="" id="mo2f_test_kba_form">
10
+ <input type="hidden" name="option" value="mo2f_validate_kba_details"/>
11
+ <input type="hidden" name="mo2f_validate_kba_details_nonce"
12
+ value="<?php echo wp_create_nonce( "mo2f-validate-kba-details-nonce" ) ?>"/>
13
+
14
+ <div id="mo2f_kba_content">
15
+ <?php if ( isset( $_SESSION['mo_2_factor_kba_questions'] ) ) {
16
+ echo $_SESSION['mo_2_factor_kba_questions'][0];
17
+ ?>
18
+ <br>
19
+ <input class="mo2f_table_textbox" style="width:227px;" type="text" name="mo2f_answer_1"
20
+ id="mo2f_answer_1" required="true" autofocus="true"
21
+ pattern="(?=\S)[A-Za-z0-9_@.$#&amp;+\-\s]{1,100}"
22
+ title="Only alphanumeric letters with special characters(_@.$#&amp;+-) are allowed."
23
+ autocomplete="off"><br><br>
24
+ <?php
25
+ echo $_SESSION['mo_2_factor_kba_questions'][1];
26
+ ?>
27
+ <br>
28
+ <input class="mo2f_table_textbox" style="width:227px;" type="text" name="mo2f_answer_2"
29
+ id="mo2f_answer_2" required="true" pattern="(?=\S)[A-Za-z0-9_@.$#&amp;+\-\s]{1,100}"
30
+ title="Only alphanumeric letters with special characters(_@.$#&amp;+-) are allowed."
31
+ autocomplete="off"><br><br>
32
+ <?php
33
+ }
34
+ ?>
35
+ </div>
36
+ <input type="button" name="back" id="go_back" class="mo_wpns_button mo_wpns_button1" value="<?php echo mo2f_lt( 'Back' ); ?>" />
37
+ <input type="submit" name="validate" id="validate" class="mo_wpns_button mo_wpns_button1"
38
+ value="<?php echo mo2f_lt( 'Validate Answers' ); ?>"/>
39
+
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="hidden" name="mo2f_go_back_nonce"
44
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
45
+ </form>
46
+ <script>
47
+ jQuery('#go_back').click(function () {
48
+ jQuery('#mo2f_go_back_form').submit();
49
+ });
50
+ </script>
51
+ <?php
52
+
53
+ }
54
+
55
+ ?>
views/test/test_twofa_miniorange_push_notification.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php function mo2f_test_miniorange_push_notification( $user ) { ?>
2
+
3
+ <h3><?php echo mo2f_lt( 'Test Push Notification' ); ?></h3>
4
+ <hr>
5
+ <div>
6
+ <br><br>
7
+ <center>
8
+ <h4><?php echo mo2f_lt( 'A Push Notification has been sent to your phone.' ); ?>
9
+ <br><?php echo mo2f_lt( 'We are waiting for your approval...' ); ?>
10
+ </h4>
11
+ <img src="<?php echo plugins_url( '/../includes/images/ajax-loader-login.gif', __FILE__); ?>"/>
12
+ </center>
13
+ <input type="button" name="back" id="go_back" class="mo_wpns_button mo_wpns_button1"
14
+ value="<?php echo mo2f_lt( 'Back' ); ?>" style="margin-top:100px;margin-left:10px;"/>
15
+ <br><br>
16
+ </div>
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>
35
+ jQuery('#go_back').click(function () {
36
+ jQuery('#mo2f_go_back_form').submit();
37
+ });
38
+
39
+ var timeout;
40
+ pollMobileValidation();
41
+
42
+ function pollMobileValidation() {
43
+ var transId = "<?php echo $_SESSION['mo2f_transactionId']; ?>";
44
+ var jsonString = "{\"txId\":\"" + transId + "\"}";
45
+ var postUrl = "<?php echo MO_HOST_NAME; ?>" + "/moas/api/auth/auth-status";
46
+
47
+ jQuery.ajax({
48
+ url: postUrl,
49
+ type: "POST",
50
+ dataType: "json",
51
+ data: jsonString,
52
+ contentType: "application/json; charset=utf-8",
53
+ success: function (result) {
54
+ var status = JSON.parse(JSON.stringify(result)).status;
55
+ if (status == 'SUCCESS') {
56
+ jQuery('#mo2f_push_success_form').submit();
57
+ } else if (status == 'ERROR' || status == 'FAILED' || status == 'DENIED') {
58
+ jQuery('#mo2f_push_error_form').submit();
59
+ } else {
60
+ timeout = setTimeout(pollMobileValidation, 3000);
61
+ }
62
+ }
63
+ });
64
+ }
65
+
66
+ </script>
67
+
68
+ <?php } ?>
views/test/test_twofa_miniorange_qrcode_authentication.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function mo2f_test_miniorange_qr_code_authentication( $user ) {
4
+ ?>
5
+ <h3><?php echo mo2f_lt( 'Test QR Code Authentication' ); ?></h3>
6
+ <hr>
7
+ <p><?php echo mo2f_lt( 'Open your miniOrange' ); ?>
8
+ <b><?php echo mo2f_lt( 'Authenticator App' ); ?></b> <?php echo mo2f_lt( 'and click on' ); ?>
9
+ <b><?php echo mo2f_lt( 'SCAN QR Code' ); ?></b> <?php echo mo2f_lt( 'to scan the QR code. Your phone should have internet connectivity to scan QR code.' ); ?>
10
+ </p>
11
+
12
+ <div style="color:indianred;">
13
+ <b><?php echo mo2f_lt( 'I am not able to scan the QR code,' ); ?> <a
14
+ data-toggle="collapse" href="#mo2f_testscanqrcode"
15
+ aria-expanded="false"><?php echo mo2f_lt( 'click here ' ); ?></a></b>
16
+ </div>
17
+ <div class="mo2f_collapse" id="mo2f_testscanqrcode">
18
+ <br><?php echo mo2f_lt( 'Follow these instructions below and try again.' ); ?>
19
+ <ol>
20
+ <li><?php echo mo2f_lt( 'Make sure your desktop screen has enough brightness.' ); ?></li>
21
+ <li><?php echo mo2f_lt( 'Open your app and click on Green button (your registered email is displayed on the button) to scan QR Code.' ); ?></li>
22
+ <li><?php echo mo2f_lt( 'If you get cross mark on QR Code then click on \'Back\' button and again click on \'Test\' link.' ); ?></li>
23
+ </ol>
24
+ </div>
25
+ <br>
26
+ <table class="mo2f_settings_table">
27
+ <div id="qr-success"></div>
28
+ <div id="displayQrCode" >
29
+ <br><?php echo '<img style="width:165px;" src="data:image/jpg;base64,' . $_SESSION['mo2f_qrCode'] . '" />'; ?>
30
+ </div>
31
+
32
+ </table>
33
+
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="mo_wpns_button mo_wpns_button1"
50
+ value="<?php echo mo2f_lt( 'Back' ); ?>"/>
51
+ </form>
52
+ </div>
53
+
54
+
55
+ <script>
56
+ var timeout;
57
+ pollMobileValidation();
58
+
59
+ function pollMobileValidation() {
60
+ var transId = "<?php echo $_SESSION['mo2f_transactionId']; ?>";
61
+ var jsonString = "{\"txId\":\"" + transId + "\"}";
62
+ var postUrl = "<?php echo MO_HOST_NAME; ?>" + "/moas/api/auth/auth-status";
63
+
64
+ jQuery.ajax({
65
+ url: postUrl,
66
+ type: "POST",
67
+ dataType: "json",
68
+ data: jsonString,
69
+ contentType: "application/json; charset=utf-8",
70
+ success: function (result) {
71
+ var status = JSON.parse(JSON.stringify(result)).status;
72
+ if (status == 'SUCCESS') {
73
+ var content = "<br><div id='success'><img style='width:165px;margin-top:-1%;margin-left:2%;' src='" + "<?php echo plugins_url( '/../includes/images/right.png', __FILE__ );?>" + "' /></div>";
74
+ jQuery("#displayQrCode").empty();
75
+ jQuery("#displayQrCode").append(content);
76
+ setTimeout(function () {
77
+ jQuery('#mo2f_mobile_authenticate_success_form').submit();
78
+ }, 1000);
79
+
80
+ } else if (status == 'ERROR' || status == 'FAILED') {
81
+ var content = "<br><div id='error'><img style='width:165px;margin-top:-1%;margin-left:2%;' src='" + "<?php echo plugins_url( '/../includes/images/wrong.png', __FILE__ );?>" + "' /></div>";
82
+ jQuery("#displayQrCode").empty();
83
+ jQuery("#displayQrCode").append(content);
84
+ setTimeout(function () {
85
+ jQuery('#mo2f_mobile_authenticate_error_form').submit();
86
+ }, 1000);
87
+ } else {
88
+ timeout = setTimeout(pollMobileValidation, 3000);
89
+ }
90
+ }
91
+ });
92
+ }
93
+
94
+ jQuery('html,body').animate({scrollTop: jQuery(document).height()}, 600);
95
+ </script>
96
+ <?php
97
+ } ?>
views/test/test_twofa_miniorange_soft_token.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php function mo2f_test_miniorange_soft_token( $user ) {?>
2
+ <div style="width:100%;">
3
+ <h3><?php echo mo2f_lt( 'Test Soft Token' ); ?></h3>
4
+ <hr>
5
+ <p><?php echo mo2f_lt( 'Open your' ); ?>
6
+ <b><?php echo mo2f_lt( 'miniOrange Authenticator App ' ); ?></b> <?php echo mo2f_lt( 'and ' ); ?>
7
+ <?php echo mo2f_lt( 'enter the' ); ?>
8
+ <b><?php echo mo2f_lt( 'one time passcode' ); ?></b> <?php echo mo2f_lt( 'shown in the App under your account.' ); ?>
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
+
17
+ <br><br>
18
+ <input type="button" name="back" id="go_back" class="mo_wpns_button mo_wpns_button1"
19
+ value="<?php echo mo2f_lt( 'Back' ); ?>"/>
20
+ <input type="submit" name="validate" id="validate" class="mo_wpns_button mo_wpns_button1"
21
+ value="<?php echo mo2f_lt( 'Validate OTP' ); ?>"/>
22
+
23
+ </form>
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
+ </div>
31
+ <script>
32
+ jQuery('#go_back').click(function () {
33
+ jQuery('#mo2f_go_back_form').submit();
34
+ });
35
+ </script>
36
+ <?php }
37
+
38
+ ?>
views/test/test_twofa_otp_over_sms.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ function mo2f_test_otp_over_sms( $user ) {
3
+
4
+ ?>
5
+ <h3><?php echo mo2f_lt( 'Test OTP Over SMS' ); ?>
6
+ <hr>
7
+ </h3>
8
+ <p><?php echo mo2f_lt( 'Enter the one time passcode sent to your registered mobile number.' ); ?></p>
9
+
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>
19
+ <br><br>
20
+ <input type="button" name="back" id="go_back" class="mo_wpns_button mo_wpns_button1"
21
+ value="<?php echo mo2f_lt( 'Back' ); ?>"/>
22
+ <input type="submit" name="validate" id="validate" class="mo_wpns_button mo_wpns_button1"
23
+ value="<?php echo mo2f_lt( 'Validate OTP' ); ?>"/>
24
+
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>
43
+ jQuery('#go_back').click(function () {
44
+ jQuery('#mo2f_go_back_form').submit();
45
+ });
46
+ jQuery('a[href=\"#resendsmslink\"]').click(function (e) {
47
+ jQuery('#mo2f_2factor_test_authentication_method_form').submit();
48
+ });
49
+ </script>
50
+
51
+ <?php } ?>
views/twofa/setup/setup_kba_questions.php CHANGED
@@ -199,4 +199,4 @@ function mo2f_configure_for_mobile_suppport_kba( $user ) {
199
  <?php
200
  }
201
 
202
- ?>
199
  <?php
200
  }
201
 
202
+ ?>
views/twofa/setup/setup_miniorange_authenticator.php CHANGED
@@ -223,4 +223,4 @@ function initialize_mobile_registration() {
223
  }, 800);
224
  </script>
225
  <?php
226
- } ?>
223
  }, 800);
224
  </script>
225
  <?php
226
+ } ?>
views/twofa/setup_twofa.php CHANGED
@@ -27,7 +27,8 @@
27
  if($testMethod=='NONE'){
28
  $testMethod = "Not Configured";
29
  }
30
- if ( $selectedMethod !== 'NONE' ) {
 
31
  $Mo2fdbQueries->update_user_details( $user->ID, array(
32
  'mo2f_configured_2FA_method' => $selectedMethod,
33
  'mo2f_' . str_replace( ' ', '', $selectedMethod ) . '_config_status' => true
@@ -56,7 +57,7 @@
56
  mo2f_show_2FA_test_screen( $user, $current_selected_method );
57
  echo '</div>';
58
  }else if ( get_user_meta( $user->ID, 'register_account_popup', true ) && $can_display_admin_features ) {
59
- display_customer_registration_forms( $user );
60
  } else {
61
  $is_NC = get_option( 'mo2f_is_NC' );
62
  $free_plan_existing_user = array(
@@ -85,7 +86,7 @@
85
  "OTP Over SMS and Email"
86
  );
87
 
88
- $standard_plan_new_user = array(
89
  "",
90
  "Email Verification",
91
  "OTP Over SMS",
@@ -98,26 +99,77 @@
98
  "Hardware Token"
99
  );
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  $free_plan_methods_existing_user = array_chunk( $free_plan_existing_user, 3 );
103
  $free_plan_methods_new_user = array_chunk( $free_plan_new_user, 3 );
104
  $standard_plan_methods_existing_user = array_chunk( $standard_plan_existing_user, 3 );
105
  $standard_plan_methods_new_user = array_chunk( $standard_plan_new_user, 3 );
106
- $premium_plan_methods_existing_user = array_chunk( array_merge( $standard_plan_existing_user, $premium_plan ), 3 );
 
107
  $premium_plan_methods_new_user = array_chunk( array_merge( $standard_plan_new_user, $premium_plan ), 3 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  ?>
 
110
  <div class="mo_wpns_setting_layout">
111
  <div>
112
  <div>
113
  <a class="mo2f_view_free_plan_auth_methods" onclick="show_free_plan_auth_methods()">
114
- <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', dirname(dirname(__FILE__))); ?>"
115
  class="mo2f_2factor_heading_images" style="margin-top: 2px;"/>
116
  <p class="mo2f_heading_style" style="padding:0px;"><?php echo mo2f_lt( 'Authentication methods' ); ?>
117
  <?php if ( $can_display_admin_features ) { ?>
118
  <span style="color:limegreen">( <?php echo mo2f_lt( 'Current Plan' ); ?> )</span>
119
  <?php } ?>
120
- <button class="button button-primary button-large" id="test" style="float:right; margin-right: 25px;" onclick="testAuthenticationMethod('<?php echo $selectedMethod; ?>');"
121
  <?php echo $is_customer_registered && ( $selectedMethod != 'NONE' ) ? "" : " disabled "; ?>>Test : <?php echo $testMethod;?>
122
  </button>
123
  </p>
@@ -126,11 +178,16 @@
126
 
127
  </div>
128
  <?php
129
- if ( in_array( $selectedMethod, array(
130
- "Google Authenticator",
131
- "miniOrange Soft Token",
132
- "Authy Authenticator"
133
- ) ) ) { ?>
 
 
 
 
 
134
  <div style="float:right;">
135
  <form name="f" method="post" action="" id="mo2f_enable_2FA_on_login_page_form">
136
  <input type="hidden" name="option" value="mo2f_enable_2FA_on_login_page_option"/>
@@ -138,36 +195,36 @@
138
  value="<?php echo wp_create_nonce( "mo2f-enable-2FA-on-login-page-option-nonce" ) ?>"/>
139
 
140
  <input type="checkbox" id="mo2f_enable_2fa_prompt_on_login_page"
141
- name="mo2f_enable_2fa_prompt_on_login_page"
142
  value="1" <?php checked( get_option( 'mo2f_enable_2fa_prompt_on_login_page' ) == 1 );
143
 
144
- if ( ! in_array( $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID ), array(
145
  'MO_2_FACTOR_PLUGIN_SETTINGS',
146
  'MO_2_FACTOR_INITIALIZE_TWO_FACTOR'
147
  ) ) ) {
148
  echo 'disabled';
149
- } ?> onChange="this.form.submit()"/>
 
150
  <?php echo mo2f_lt( 'Enable 2FA prompt on the WP Login Page' ); ?>
151
  </form>
152
  </div>
153
- <br><br>
 
 
 
 
 
 
154
  <?php
155
- }
156
-
 
 
 
157
  echo mo2f_create_2fa_form( $user, "free_plan", $is_NC ? $free_plan_methods_new_user : $free_plan_methods_existing_user, $can_display_admin_features ); ?>
158
  </div>
159
  <hr>
160
  <?php if ( $can_display_admin_features ) { ?>
161
- <div id="mo2f_standard_plan">
162
- <a class="mo2f_view_standard_plan_auth_methods" onclick="show_standard_plan_auth_methods()">
163
- <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', dirname(dirname(__FILE__)) ); ?>"
164
- class="mo2f_2factor_heading_images"/>
165
- <p class="mo2f_heading_style"><span > <?php echo mo2f_lt( 'Standard plan - Authentication methods' ); ?>
166
- *</span></p>
167
- </a>
168
- <?php echo mo2f_create_2fa_form( $user, "standard_plan", $is_NC ? $standard_plan_methods_new_user : $standard_plan_methods_existing_user ); ?>
169
- </div>
170
- <hr>
171
  <div>
172
  <span id="mo2f_premium_plan"> <a class="mo2f_view_premium_plan_auth_methods" onclick="show_premium_auth_methods()">
173
  <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', dirname(dirname(__FILE__))); ?>"
@@ -179,12 +236,12 @@
179
  </div>
180
  <hr>
181
  <br>
182
- <p>
183
  * <?php echo mo2f_lt( 'These authentication methods are available in the STANDARD and PREMIUM plans' ); ?>
184
  . <a
185
  href="admin.php?page=mo_2fa_upgrade"><?php echo mo2f_lt( 'Click here' ); ?></a> <?php echo mo2f_lt( 'to learn more' ) ?>
186
  .</p>
187
- <?php } ?>
188
  <form name="f" method="post" action="" id="mo2f_2factor_test_authentication_method_form">
189
  <input type="hidden" name="option" value="mo_2factor_test_authentication_method"/>
190
  <input type="hidden" name="mo2f_configured_2FA_method_test" id="mo2f_configured_2FA_method_test"/>
@@ -219,8 +276,15 @@
219
  });
220
 
221
  jQuery('#closeEnterEmail').click(function(){
222
- close_modal();
223
  });
 
 
 
 
 
 
 
224
  jQuery('#save_entered_email').click(function(){
225
  var email = jQuery('#emailEntered').val();
226
  var nonce = '<?php echo wp_create_nonce('EmailVerificationSaveNonce');?>';
@@ -228,11 +292,11 @@
228
  if(email != '')
229
  {
230
  var data = {
231
- 'action' : 'wpns_login_security',
232
- 'wpns_loginsecurity_ajax' : 'wpns_save_email_verification',
233
- 'nonce' : nonce,
234
- 'email' : email,
235
- 'user_id' : user_id
236
  };
237
  jQuery.post(ajaxurl, data, function(response) {
238
  var response = response.replace(/\s+/g,' ').trim();
@@ -240,18 +304,24 @@
240
  {
241
  jQuery('#mo2f_configured_2FA_method_free_plan').val('EmailVerification');
242
  jQuery('#mo2f_selected_action_free_plan').val('select2factor');
243
- jQuery('#mo2f_save_free_plan_auth_methods_form').submit();
244
  }
245
  else if(response == "NonceDidNotMatch")
246
  {
247
- //error while saving
248
- alert("error while saving");
 
 
 
 
 
 
249
  }
250
  else
251
  {
252
- //invalid email
253
- alert("invalid email");
254
-
255
  }
256
  close_modal();
257
  });
@@ -338,9 +408,28 @@
338
 
339
  // cosole.log('saasdsa');
340
  function configureOrSet2ndFactor_free_plan(authMethod, action) {
341
- jQuery('#mo2f_configured_2FA_method_free_plan').val(authMethod);
342
- jQuery('#mo2f_selected_action_free_plan').val(action);
343
- jQuery('#mo2f_save_free_plan_auth_methods_form').submit();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  }
345
 
346
  function testAuthenticationMethod(authMethod) {
@@ -354,25 +443,13 @@
354
  jQuery('#mo2f_2factor_resume_flow_driven_setup_form').submit();
355
  }
356
 
357
- jQuery("#mo2f_standard_plan_auth_methods").hide();
358
-
359
- function show_standard_plan_auth_methods() {
360
- jQuery("#mo2f_standard_plan_auth_methods").slideToggle(1000);
361
- jQuery("#mo2f_free_plan_auth_methods").hide();
362
- jQuery("#mo2f_premium_plan_auth_methods").hide();
363
- }
364
 
365
  function show_free_plan_auth_methods() {
366
- jQuery("#mo2f_free_plan_auth_methods").slideToggle(1000);
367
- jQuery("#mo2f_standard_plan_auth_methods").hide();
368
- jQuery("#mo2f_premium_plan_auth_methods").hide();
369
  }
370
 
371
- jQuery("#mo2f_premium_plan_auth_methods").hide();
372
 
373
  function show_premium_auth_methods() {
374
- jQuery("#mo2f_free_plan_auth_methods").hide();
375
- jQuery("#mo2f_standard_plan_auth_methods").hide();
376
  jQuery("#mo2f_premium_plan_auth_methods").slideToggle(1000);
377
  }
378
 
@@ -382,5 +459,9 @@
382
  jQuery("#how_to_configure_2fa").slideToggle(700);
383
  }
384
 
 
 
 
 
385
  </script>
386
  <?php } ?>
27
  if($testMethod=='NONE'){
28
  $testMethod = "Not Configured";
29
  }
30
+
31
+ if ( $selectedMethod !== 'NONE' and !MO2F_IS_ONPREM) {
32
  $Mo2fdbQueries->update_user_details( $user->ID, array(
33
  'mo2f_configured_2FA_method' => $selectedMethod,
34
  'mo2f_' . str_replace( ' ', '', $selectedMethod ) . '_config_status' => true
57
  mo2f_show_2FA_test_screen( $user, $current_selected_method );
58
  echo '</div>';
59
  }else if ( get_user_meta( $user->ID, 'register_account_popup', true ) && $can_display_admin_features ) {
60
+ display_customer_registration_forms( $user );
61
  } else {
62
  $is_NC = get_option( 'mo2f_is_NC' );
63
  $free_plan_existing_user = array(
86
  "OTP Over SMS and Email"
87
  );
88
 
89
+ $standard_plan_new_user = array(
90
  "",
91
  "Email Verification",
92
  "OTP Over SMS",
99
  "Hardware Token"
100
  );
101
 
102
+ if(MO2F_IS_ONPREM)
103
+ {
104
+ $free_plan_existing_user = array(
105
+ "Email Verification",
106
+ "Security Questions",
107
+ "Google Authenticator",
108
+ );
109
+
110
+ $free_plan_new_user = array(
111
+ "Google Authenticator",
112
+ "Security Questions",
113
+ );
114
+ $premium_plan = array(
115
+ "Hardware Token",
116
+ "miniOrange QR Code Authentication",
117
+ "miniOrange Soft Token",
118
+ "miniOrange Push Notification",
119
+ "Authy Authenticator"
120
+
121
+ );
122
+ $standard_plan_existing_user = array(
123
+ "",
124
+ "OTP Over Email",
125
+ "OTP Over SMS and Email",
126
+ "OTP Over SMS"
127
+ );
128
+ $standard_plan_new_user = array(
129
+ "",
130
+ "Email Verification",
131
+ "OTP Over SMS",
132
+ "OTP Over Email",
133
+ "OTP Over SMS and Email"
134
+ );
135
+ }
136
 
137
  $free_plan_methods_existing_user = array_chunk( $free_plan_existing_user, 3 );
138
  $free_plan_methods_new_user = array_chunk( $free_plan_new_user, 3 );
139
  $standard_plan_methods_existing_user = array_chunk( $standard_plan_existing_user, 3 );
140
  $standard_plan_methods_new_user = array_chunk( $standard_plan_new_user, 3 );
141
+
142
+ $premium_plan_methods_existing_user = array_chunk( array_merge( $standard_plan_existing_user, $premium_plan) , 3 );
143
  $premium_plan_methods_new_user = array_chunk( array_merge( $standard_plan_new_user, $premium_plan ), 3 );
144
+ if(MO2F_IS_ONPREM)
145
+ {
146
+ $selectedMethod = get_user_meta(get_current_user_id(),'currentMethod',true);
147
+ $is_customer_registered = true;
148
+ $testMethod = $selectedMethod;
149
+ if($selectedMethod == '')
150
+ {
151
+ $selectedMethod = 'NONE';
152
+ $testMethod = 'Not Configured';
153
+ }
154
+ // $premium_plan_methods_existing_user = array_chunk( array_merge( $standard_plan_existing_user, $premium_plan , 3 );
155
+ //$premium_plan_methods_new_user = array_chunk( array_merge( $standard_plan_new_user, $premium_plan ), 3 );
156
+
157
+
158
+ }
159
 
160
  ?>
161
+ <div id="wpns_message"></div>
162
  <div class="mo_wpns_setting_layout">
163
  <div>
164
  <div>
165
  <a class="mo2f_view_free_plan_auth_methods" onclick="show_free_plan_auth_methods()">
166
+ <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', dirname(dirname(__FILE__ ))); ?>"
167
  class="mo2f_2factor_heading_images" style="margin-top: 2px;"/>
168
  <p class="mo2f_heading_style" style="padding:0px;"><?php echo mo2f_lt( 'Authentication methods' ); ?>
169
  <?php if ( $can_display_admin_features ) { ?>
170
  <span style="color:limegreen">( <?php echo mo2f_lt( 'Current Plan' ); ?> )</span>
171
  <?php } ?>
172
+ <button class="btn btn-primary btn-large" id="test" style="float:right; margin-right: 20px; height: 36px" onclick="testAuthenticationMethod('<?php echo $selectedMethod; ?>');"
173
  <?php echo $is_customer_registered && ( $selectedMethod != 'NONE' ) ? "" : " disabled "; ?>>Test : <?php echo $testMethod;?>
174
  </button>
175
  </p>
178
 
179
  </div>
180
  <?php
181
+ // if ( in_array( $selectedMethod, array(
182
+ // "Google Authenticator",
183
+ // "miniOrange Soft Token",
184
+ // "Authy Authenticator",
185
+ // "Security Questions",
186
+ // "miniOrange Push Notification",
187
+ // "miniOrange QR Code Authentication"
188
+ // ) ) ) {
189
+ ?>
190
+ <?php if(current_user_can('administrator')){ ?>
191
  <div style="float:right;">
192
  <form name="f" method="post" action="" id="mo2f_enable_2FA_on_login_page_form">
193
  <input type="hidden" name="option" value="mo2f_enable_2FA_on_login_page_option"/>
195
  value="<?php echo wp_create_nonce( "mo2f-enable-2FA-on-login-page-option-nonce" ) ?>"/>
196
 
197
  <input type="checkbox" id="mo2f_enable_2fa_prompt_on_login_page"
198
+ name="mo2f_enable_2fa_prompt_on_login_page"
199
  value="1" <?php checked( get_option( 'mo2f_enable_2fa_prompt_on_login_page' ) == 1 );
200
 
201
+ if (!current_user_can('administrator') && ! in_array( $Mo2fdbQueries->get_user_detail( 'mo_2factor_user_registration_status', $user->ID ), array(
202
  'MO_2_FACTOR_PLUGIN_SETTINGS',
203
  'MO_2_FACTOR_INITIALIZE_TWO_FACTOR'
204
  ) ) ) {
205
  echo 'disabled';
206
+ }
207
+ ?> onChange="document.getElementById('mo2f_enable_2fa_prompt_on_login_page').form.submit()"/>
208
  <?php echo mo2f_lt( 'Enable 2FA prompt on the WP Login Page' ); ?>
209
  </form>
210
  </div>
211
+
212
+ <?php
213
+ ?>
214
+ <br>
215
+ <?php
216
+ }
217
+ ?>
218
  <?php
219
+ // }
220
+ // else
221
+ // {
222
+ // update_option( 'mo2f_enable_2fa_prompt_on_login_page', 1 );
223
+ // }
224
  echo mo2f_create_2fa_form( $user, "free_plan", $is_NC ? $free_plan_methods_new_user : $free_plan_methods_existing_user, $can_display_admin_features ); ?>
225
  </div>
226
  <hr>
227
  <?php if ( $can_display_admin_features ) { ?>
 
 
 
 
 
 
 
 
 
 
228
  <div>
229
  <span id="mo2f_premium_plan"> <a class="mo2f_view_premium_plan_auth_methods" onclick="show_premium_auth_methods()">
230
  <img src="<?php echo plugins_url( 'includes/images/right-arrow.png"', dirname(dirname(__FILE__))); ?>"
236
  </div>
237
  <hr>
238
  <br>
239
+ <p><?php if(current_user_can('administrator')){ ?>
240
  * <?php echo mo2f_lt( 'These authentication methods are available in the STANDARD and PREMIUM plans' ); ?>
241
  . <a
242
  href="admin.php?page=mo_2fa_upgrade"><?php echo mo2f_lt( 'Click here' ); ?></a> <?php echo mo2f_lt( 'to learn more' ) ?>
243
  .</p>
244
+ <?php }} ?>
245
  <form name="f" method="post" action="" id="mo2f_2factor_test_authentication_method_form">
246
  <input type="hidden" name="option" value="mo_2factor_test_authentication_method"/>
247
  <input type="hidden" name="mo2f_configured_2FA_method_test" id="mo2f_configured_2FA_method_test"/>
276
  });
277
 
278
  jQuery('#closeEnterEmail').click(function(){
279
+ jQuery('#EnterEmail').css('display', 'none');
280
  });
281
+ var emailinput = document.getElementById("emailEntered");
282
+ emailinput.addEventListener("keyup", function(event) {
283
+ if (event.keyCode === 13) {
284
+ event.preventDefault();
285
+ document.getElementById("save_entered_email").click();
286
+ }
287
+ });
288
  jQuery('#save_entered_email').click(function(){
289
  var email = jQuery('#emailEntered').val();
290
  var nonce = '<?php echo wp_create_nonce('EmailVerificationSaveNonce');?>';
292
  if(email != '')
293
  {
294
  var data = {
295
+ 'action' : 'mo_two_factor_ajax',
296
+ 'mo_2f_two_factor_ajax' : 'mo2f_save_email_verification',
297
+ 'nonce' : nonce,
298
+ 'email' : email,
299
+ 'user_id' : user_id
300
  };
301
  jQuery.post(ajaxurl, data, function(response) {
302
  var response = response.replace(/\s+/g,' ').trim();
304
  {
305
  jQuery('#mo2f_configured_2FA_method_free_plan').val('EmailVerification');
306
  jQuery('#mo2f_selected_action_free_plan').val('select2factor');
307
+ jQuery('#mo2f_save_free_plan_auth_methods_form').submit();
308
  }
309
  else if(response == "NonceDidNotMatch")
310
  {
311
+ jQuery('#wpns_message').empty();
312
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; An unknown error has occured.</div></div>");
313
+ window.onload = nav_popup();
314
+ }else if(response=="USER_LIMIT_EXCEEDED"){
315
+ jQuery('#EnterEmail').css('display', 'none');
316
+ jQuery('#wpns_message').empty();
317
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Your limit of 3 users has exceeded. Please upgrade to premium plans for more users.</div></div>");
318
+ window.onload = nav_popup();
319
  }
320
  else
321
  {
322
+ jQuery('#wpns_message').empty()
323
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Invalid Email.</div></div>");
324
+ window.onload = nav_popup();
325
  }
326
  close_modal();
327
  });
408
 
409
  // cosole.log('saasdsa');
410
  function configureOrSet2ndFactor_free_plan(authMethod, action) {
411
+ if(authMethod == 'EmailVerification')
412
+ {
413
+ var is_onprem = '<?php echo MO2F_IS_ONPREM;?>';
414
+ var is_registered = '<?php echo $email_registered;?>';
415
+ if(is_onprem == 1 && is_registered!=0 && action != 'select2factor')
416
+ {
417
+ jQuery('#EnterEmail').css('display', 'block');
418
+ jQuery('.modal-content').css('width', '35%');
419
+ }
420
+ else
421
+ {
422
+ jQuery('#mo2f_configured_2FA_method_free_plan').val(authMethod);
423
+ jQuery('#mo2f_selected_action_free_plan').val(action);
424
+ jQuery('#mo2f_save_free_plan_auth_methods_form').submit();
425
+ }
426
+ }
427
+ else
428
+ {
429
+ jQuery('#mo2f_configured_2FA_method_free_plan').val(authMethod);
430
+ jQuery('#mo2f_selected_action_free_plan').val(action);
431
+ jQuery('#mo2f_save_free_plan_auth_methods_form').submit();
432
+ }
433
  }
434
 
435
  function testAuthenticationMethod(authMethod) {
443
  jQuery('#mo2f_2factor_resume_flow_driven_setup_form').submit();
444
  }
445
 
 
 
 
 
 
 
 
446
 
447
  function show_free_plan_auth_methods() {
448
+ jQuery("#mo2f_free_plan_auth_methods").slideToggle(1000);
 
 
449
  }
450
 
 
451
 
452
  function show_premium_auth_methods() {
 
 
453
  jQuery("#mo2f_premium_plan_auth_methods").slideToggle(1000);
454
  }
455
 
459
  jQuery("#how_to_configure_2fa").slideToggle(700);
460
  }
461
 
462
+ function nav_popup() {
463
+ document.getElementById("notice_div").style.width = "40%";
464
+ setTimeout(function(){ $('#notice_div').fadeOut('slow'); }, 3000);
465
+ }
466
  </script>
467
  <?php } ?>
views/twofa/test/test_twofa_email_verification.php CHANGED
@@ -1,4 +1,12 @@
1
- <?php function mo2f_test_email_verification() { ?>
 
 
 
 
 
 
 
 
2
 
3
  <h3><?php echo mo2f_lt( 'Test Email Verification' ); ?></h3>
4
  <hr>
@@ -19,58 +27,96 @@
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>
38
  jQuery('#go_back').click(function () {
39
  jQuery('#mo2f_go_back_form').submit();
40
  });
 
 
41
 
 
 
 
 
 
 
42
  var timeout;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
-
46
- pollMobileValidation();
47
- function pollMobileValidation() {
48
- var transId = "<?php echo $_SESSION['mo2f_transactionId']; ?>";
49
- var jsonString = "{\"txId\":\"" + transId + "\"}";
50
- var postUrl = "<?php echo MO_HOST_NAME; ?>" + "/moas/api/auth/auth-status";
51
-
52
- jQuery.ajax({
53
- url: postUrl,
54
- type: "POST",
55
- dataType: "json",
56
- data: jsonString,
57
- contentType: "application/json; charset=utf-8",
58
- success: function (result) {
59
- var status = JSON.parse(JSON.stringify(result)).status;
60
- if (status == 'SUCCESS') {
61
- jQuery('#mo2f_out_of_band_success_form').submit();
62
- } else if (status == 'ERROR' || status == 'FAILED' || status == 'DENIED') {
63
- jQuery('#mo2f_out_of_band_error_form').submit();
64
- } else {
65
- timeout = setTimeout(pollMobileValidation, 3000);
66
- }
67
  }
68
- });
69
- }
70
-
71
-
72
- </script>
73
 
74
  <?php }
 
75
 
76
- ?>
1
+ <?php
2
+ function mo2f_test_email_verification() {
3
+ $mo2f_dirName = dirname(__FILE__);
4
+ $mo2f_dirName = explode('wp-content', $mo2f_dirName);
5
+ $mo2f_dirName = explode('views', $mo2f_dirName[1]);
6
+
7
+ $checkEV = get_site_option('siteurl').DIRECTORY_SEPARATOR."wp-content".$mo2f_dirName[0]."handler".DIRECTORY_SEPARATOR."two_fa_pass2login.php";
8
+ $checkEV = 'http://localhost/onpremchanges/wordpress\wp-content\plugins\miniorange-2-factor-authentication\viewshandler\two_fa_pass2login.php';
9
+ ?>
10
 
11
  <h3><?php echo mo2f_lt( 'Test Email Verification' ); ?></h3>
12
  <hr>
27
 
28
  <form name="f" method="post" action="" id="mo2f_go_back_form">
29
  <input type="hidden" name="option" value="mo2f_go_back"/>
30
+ <input type="hidden" name="mo2f_go_back_nonce"
31
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
32
  </form>
33
  <form name="f" method="post" id="mo2f_out_of_band_success_form" action="">
34
  <input type="hidden" name="option" value="mo2f_out_of_band_success"/>
35
+ <input type="hidden" name="mo2f_out_of_band_success_nonce"
36
+ value="<?php echo wp_create_nonce( "mo2f-out-of-band-success-nonce" ) ?>"/>
37
+ <input type="hidden" name="TxidEmail" value="<?php echo $_SESSION['txid']; ?>"/>
38
  </form>
39
  <form name="f" method="post" id="mo2f_out_of_band_error_form" action="">
40
  <input type="hidden" name="option" value="mo2f_out_of_band_error"/>
41
+
42
+ <input type="hidden" name="mo2f_out_of_band_error_nonce"
43
+ value="<?php echo wp_create_nonce( "mo2f-out-of-band-error-nonce" ) ?>"/>
44
  </form>
45
 
46
+ <script type="text/javascript">
47
  jQuery('#go_back').click(function () {
48
  jQuery('#mo2f_go_back_form').submit();
49
  });
50
+ </script>
51
+ <?php
52
 
53
+ if(MO2F_IS_ONPREM)
54
+ {
55
+ $otpToken = isset($_SESSION['otpToken']) ? $_SESSION['otpToken'] : '';
56
+ $txid = isset($_SESSION["txid"]) ? $_SESSION["txid"] : '';
57
+ ?>
58
+ <script type="text/javascript">
59
  var timeout;
60
+ pollMobileValidation();
61
+ function pollMobileValidation() {
62
+ var otpToken = "<?php echo $otpToken; ?>";
63
+ var jsonString = "{\"otpToken\":\"" + otpToken + "\"}";
64
+ var txid = '<?php echo $txid;?>';
65
+ var data = {
66
+ 'action' : 'mo_two_factor_ajax',
67
+ 'mo_2f_two_factor_ajax' : 'CheckEVStatus',
68
+ 'txid' : txid
69
+ };
70
+ jQuery.post(ajaxurl, data, function(response) {
71
+ var response = response.replace(/\s+/g,' ').trim();
72
+ var status = response;
73
+ if (status == '1') {
74
+ jQuery('#mo2f_out_of_band_success_form').submit();
75
+ } else if (status == 'ERROR' || status == 'FAILED' || status == 'DENIED' || status =='0') {
76
+ jQuery('#mo2f_out_of_band_error_form').submit();
77
+ } else {
78
+ timeout = setTimeout(pollMobileValidation, 1000);
79
+ }
80
+ });
81
+
82
+ }
83
 
84
+ </script>
85
+ <?php
86
+ }
87
+ else
88
+ {
89
+ $mo2f_transactionId = isset($_SESSION['mo2f_transactionId']) ? $_SESSION['mo2f_transactionId'] : '';
90
+ ?>
91
+ <script type="text/javascript">
92
+ var timeout;
93
+ pollMobileValidation();
94
+ function pollMobileValidation() {
95
+ var transId = "<?php echo $mo2f_transactionId; ?>";
96
+ var jsonString = "{\"txId\":\"" + transId + "\"}";
97
+ var postUrl = "<?php echo MO_HOST_NAME; ?>" + "/moas/api/auth/auth-status";
98
 
99
+ jQuery.ajax({
100
+ url: postUrl,
101
+ type: "POST",
102
+ dataType: "json",
103
+ data: jsonString,
104
+ contentType: "application/json; charset=utf-8",
105
+ success: function (result) {
106
+ var status = JSON.parse(JSON.stringify(result)).status;
107
+ if (status == 'SUCCESS') {
108
+ jQuery('#mo2f_out_of_band_success_form').submit();
109
+ } else if (status == 'ERROR' || status == 'FAILED' || status == 'DENIED') {
110
+ jQuery('#mo2f_out_of_band_error_form').submit();
111
+ } else {
112
+ timeout = setTimeout(pollMobileValidation, 3000);
 
 
 
 
 
 
 
 
113
  }
114
+ }
115
+ });
116
+ }
117
+ </script>
 
118
 
119
  <?php }
120
+ }
121
 
122
+ ?>
views/twofa/test/test_twofa_kba_questions.php CHANGED
@@ -1,6 +1,67 @@
1
- <?php
2
- function mo2f_test_kba_security_questions( $user ) {
3
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  <h3><?php echo mo2f_lt( 'Test Security Questions( KBA )' ); ?></h3>
5
  <hr>
6
  <br>
@@ -49,7 +110,7 @@
49
  });
50
  </script>
51
  <?php
52
-
53
  }
54
 
55
  ?>
1
+ <?php function mo2f_test_kba_security_questions( $user ) {
2
+ $onprem = MO2F_IS_ONPREM;
3
+ ?>
4
+
5
+ <?php
6
+ if($onprem){
7
+ ?>
8
+ <h3><?php echo mo2f_lt( 'Test Security Questions( KBA )' ); ?></h3>
9
+ <hr>
10
+ <br>
11
+
12
+
13
+ <form name="f" method="post" action="" id="mo2f_test_kba_form">
14
+ <input type="hidden" name="option" value="mo2f_validate_kba_details"/>
15
+ <input type="hidden" name="mo2f_validate_kba_details_nonce"
16
+ value="<?php echo wp_create_nonce( "mo2f-validate-kba-details-nonce" ) ?>"/>
17
+
18
+ <div id="mo2f_kba_content">
19
+ <?php
20
+ $ques = (get_user_meta($user->ID,'kba_questions_user'));
21
+ $ques = $ques[0];
22
+ /*if ( isset( $_SESSION['mo_2_factor_kba_questions'] ) ) {*/
23
+ echo $ques[0];
24
+ ?>
25
+ <br>
26
+ <input class="mo2f_table_textbox" style="width:227px;" type="text" name="mo2f_answer_1"
27
+ id="mo2f_answer_1" required="true" autofocus="true"
28
+ pattern="(?=\S)[A-Za-z0-9_@.$#&amp;+\-\s]{1,100}"
29
+ title="Only alphanumeric letters with special characters(_@.$#&amp;+-) are allowed."
30
+ autocomplete="off"><br><br>
31
+ <?php
32
+ echo $ques[1];
33
+ ?>
34
+ <br>
35
+ <input class="mo2f_table_textbox" style="width:227px;" type="text" name="mo2f_answer_2"
36
+ id="mo2f_answer_2" required="true" pattern="(?=\S)[A-Za-z0-9_@.$#&amp;+\-\s]{1,100}"
37
+ title="Only alphanumeric letters with special characters(_@.$#&amp;+-) are allowed."
38
+ autocomplete="off"><br><br>
39
+ <?php
40
+ //}
41
+ ?>
42
+ </div>
43
+ <input type="button" name="back" id="go_back" class="mo_wpns_button mo_wpns_button1" value="<?php echo mo2f_lt( 'Back' ); ?>" />
44
+ <input type="submit" name="validate" id="validate" class="mo_wpns_button mo_wpns_button1"
45
+ value="<?php echo mo2f_lt( 'Validate Answers' ); ?>"/>
46
+
47
+ </form>
48
+ <form name="f" method="post" action="" id="mo2f_go_back_form">
49
+ <input type="hidden" name="option" value="mo2f_go_back"/>
50
+ <input type="hidden" name="mo2f_go_back_nonce"
51
+ value="<?php echo wp_create_nonce( "mo2f-go-back-nonce" ) ?>"/>
52
+ </form>
53
+ <script>
54
+ jQuery('#go_back').click(function () {
55
+ jQuery('#mo2f_go_back_form').submit();
56
+ });
57
+ </script>
58
+ <?php
59
+ }
60
+
61
+ else{
62
+ ?>
63
+
64
+
65
  <h3><?php echo mo2f_lt( 'Test Security Questions( KBA )' ); ?></h3>
66
  <hr>
67
  <br>
110
  });
111
  </script>
112
  <?php
113
+ }
114
  }
115
 
116
  ?>
views/twofa/test/test_twofa_miniorange_push_notification.php CHANGED
@@ -65,4 +65,4 @@
65
 
66
  </script>
67
 
68
- <?php } ?>
65
 
66
  </script>
67
 
68
+ <?php } ?>
views/twofa/test/test_twofa_miniorange_qrcode_authentication.php CHANGED
@@ -94,4 +94,4 @@ function mo2f_test_miniorange_qr_code_authentication( $user ) {
94
  jQuery('html,body').animate({scrollTop: jQuery(document).height()}, 600);
95
  </script>
96
  <?php
97
- } ?>
94
  jQuery('html,body').animate({scrollTop: jQuery(document).height()}, 600);
95
  </script>
96
  <?php
97
+ } ?>
views/twofa/two_fa.php CHANGED
@@ -1,39 +1,50 @@
1
  <div class="mo_wpns_tab">
2
  <button class="tablinks" onclick="openTab2fa(this)" id="setup_2fa">Setup Two Factor</button>
3
  <?php
4
- if( !get_option( 'mo2f_is_NC' ))
5
- {
6
- ?>
7
- <button class="tablinks" onclick="openTab2fa(this)" id="login_option_2fa">Login Option</button>
8
- <button class="tablinks" onclick="openTab2fa(this)" id="custom_form_2fa">Integration</button>
9
- <?php
10
- }
11
- else
12
- {
13
- ?>
14
- <button class="tablinks" onclick="openTab2fa(this)" id="rba_2fa">Remember Device</button>
15
- <button class="tablinks" onclick="openTab2fa(this)" id="custom_login_2fa">Personalization</button>
16
- <button class="tablinks" onclick="openTab2fa(this)" id="custom_form_2fa">Integration</button>
17
- <button class="tablinks" onclick="openTab2fa(this)" id="shortcode_2fa">Shortcode</button>
18
- <?php
19
- }
 
 
 
20
  ?>
 
 
 
 
21
  <button class="tablinks" onclick="openTab2fa(this)" id="video_guide_2fa">Video Guide</button>
 
 
 
 
 
 
 
 
22
  </div>
23
- <br>
24
- <div id="mo_scan_message" ></div>
25
-
26
  <div class="mo_wpns_divided_layout" id="setup_2fa_div">
27
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'setup_twofa.php'; ?>
28
  </div>
29
-
30
-
31
- <div class="mo_wpns_divided_layout" id="rba_2fa_div">
32
  <?php
33
  if ( get_option( 'mo2f_rba_installed' ) )
34
  mo2f_rba_description($mo2f_user_email);
35
  else
36
- include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_rba.php';
37
  ?>
38
  </div>
39
  <div class="mo_wpns_divided_layout" id="custom_login_2fa_div">
@@ -41,7 +52,7 @@
41
  if ( get_option( 'mo2f_personalization_installed' ) )
42
  mo2f_personalization_description($mo2f_user_email);
43
  else
44
- include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_custom_login.php';
45
  ?>
46
  </div>
47
  <div class="mo_wpns_divided_layout" id="shortcode_2fa_div">
@@ -49,26 +60,26 @@
49
  if ( get_option( 'mo2f_shortcode_installed' ) )
50
  mo2f_shortcode_description($mo2f_user_email);
51
  else
52
- include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_shortcode.php';
53
  ?>
54
  </div>
55
-
56
  <div class="mo_wpns_divided_layout" id="login_option_2fa_div">
57
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_login_option.php'; ?>
58
  </div>
59
  <div class="mo_wpns_divided_layout" id="custom_form_2fa_div">
60
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_custom_form.php'; ?>
61
  </div>
62
  <div class="mo_wpns_divided_layout" id="video_guide_2fa_div">
63
- <?php include_once $dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_video_guide.php'; ?>
 
 
 
64
  </div>
65
  <script>
66
  jQuery("#setup_2fa_div").css("display", "block");
67
-
68
  jQuery("#rba_2fa_div").css("display", "none");
69
  jQuery("#custom_login_2fa_div").css("display", "none");
70
  jQuery("#shortcode_2fa_div").css("display", "none");
71
-
72
  jQuery("#login_option_2fa_div").css("display", "none");
73
  jQuery("#custom_form_2fa_div").css("display", "none");
74
  jQuery("#video_guide_2fa_div").css("display", "none");
@@ -76,7 +87,7 @@
76
  jQuery("#setup_2fa").addClass("active");
77
  function openTab2fa(elmt){
78
  var tabname = elmt.id;
79
- var tabarray = ["setup_2fa","rba_2fa","custom_login_2fa","shortcode_2fa","login_option_2fa", "custom_form_2fa", "video_guide_2fa"];
80
  for (var i = 0; i < tabarray.length; i++) {
81
  if(tabarray[i] == tabname){
82
  jQuery("#"+tabarray[i]).addClass("active");
@@ -88,13 +99,11 @@
88
  }
89
  localStorage.setItem("lastTab2fa", tabname);
90
  }
91
- var tab = localStorage.getItem("lastTab2fa");
92
-
93
  if(tab == "setup_twofa"){
94
  document.getElementById("setup_2fa").click();
95
- }
96
-
97
- else if(tab == "rba_2fa"){
98
  document.getElementById("rba_2fa").click();
99
  }
100
  else if(tab == "custom_login_2fa"){
@@ -104,7 +113,7 @@
104
  document.getElementById("shortcode_2fa").click();
105
  }
106
  else if(tab == "login_option_2fa"){
107
- document.getElementById("add_on_2fa").click();
108
  }
109
  else if(tab == "custom_form_2fa"){
110
  document.getElementById("custom_form_2fa").click();
@@ -112,7 +121,11 @@
112
  else if(tab == "video_guide_2fa"){
113
  document.getElementById("video_guide_2fa").click();
114
  }
 
 
 
 
115
  else{
116
  document.getElementById("setup_2fa").click();
117
  }
118
- </script>
1
  <div class="mo_wpns_tab">
2
  <button class="tablinks" onclick="openTab2fa(this)" id="setup_2fa">Setup Two Factor</button>
3
  <?php
4
+ if(current_user_can('administrator'))
5
+ {
6
+ if( !get_option( 'mo2f_is_NC' ))
7
+ {
8
+ ?>
9
+ <button class="tablinks" onclick="openTab2fa(this)" id="login_option_2fa">Login Option</button>
10
+ <button class="tablinks" onclick="openTab2fa(this)" id="custom_form_2fa">Integration</button>
11
+ <?php
12
+ }
13
+ else
14
+ {
15
+ ?>
16
+ <button class="tablinks" onclick="openTab2fa(this)" id="rba_2fa">Remember Device</button>
17
+ <button class="tablinks" onclick="openTab2fa(this)" id="custom_login_2fa">Personalization</button>
18
+ <button class="tablinks" onclick="openTab2fa(this)" id="custom_form_2fa">Integration</button>
19
+ <button class="tablinks" onclick="openTab2fa(this)" id="shortcode_2fa">Shortcode</button>
20
+ <?php
21
+ }
22
+
23
  ?>
24
+
25
+
26
+ <?php } ?>
27
+
28
  <button class="tablinks" onclick="openTab2fa(this)" id="video_guide_2fa">Video Guide</button>
29
+ <?php
30
+ if(current_user_can('administrator') )
31
+ {
32
+ ?>
33
+ <button class="tablinks" onclick="openTab2fa(this)" id="unlimittedUser_2fa">Multiple Users [Free]</button>
34
+ <?php
35
+ }
36
+ ?>
37
  </div>
38
+ <div id="mo_scan_message" style=" padding-top:8px"></div>
 
 
39
  <div class="mo_wpns_divided_layout" id="setup_2fa_div">
40
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'setup_twofa.php'; ?>
41
  </div>
42
+ <div class="mo_wpns_divided_layout" id="rba_2fa_div">
 
 
43
  <?php
44
  if ( get_option( 'mo2f_rba_installed' ) )
45
  mo2f_rba_description($mo2f_user_email);
46
  else
47
+ include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_rba.php';
48
  ?>
49
  </div>
50
  <div class="mo_wpns_divided_layout" id="custom_login_2fa_div">
52
  if ( get_option( 'mo2f_personalization_installed' ) )
53
  mo2f_personalization_description($mo2f_user_email);
54
  else
55
+ include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_custom_login.php';
56
  ?>
57
  </div>
58
  <div class="mo_wpns_divided_layout" id="shortcode_2fa_div">
60
  if ( get_option( 'mo2f_shortcode_installed' ) )
61
  mo2f_shortcode_description($mo2f_user_email);
62
  else
63
+ include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_shortcode.php';
64
  ?>
65
  </div>
 
66
  <div class="mo_wpns_divided_layout" id="login_option_2fa_div">
67
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_login_option.php'; ?>
68
  </div>
69
  <div class="mo_wpns_divided_layout" id="custom_form_2fa_div">
70
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_custom_form.php'; ?>
71
  </div>
72
  <div class="mo_wpns_divided_layout" id="video_guide_2fa_div">
73
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_video_guide.php'; ?>
74
+ </div>
75
+ <div class="mo_wpns_divided_layout" id="unlimittedUser_2fa_div">
76
+ <?php include_once $mo2f_dirName . 'controllers'.DIRECTORY_SEPARATOR.'twofa'.DIRECTORY_SEPARATOR.'two_fa_unlimittedUser.php'; ?>
77
  </div>
78
  <script>
79
  jQuery("#setup_2fa_div").css("display", "block");
 
80
  jQuery("#rba_2fa_div").css("display", "none");
81
  jQuery("#custom_login_2fa_div").css("display", "none");
82
  jQuery("#shortcode_2fa_div").css("display", "none");
 
83
  jQuery("#login_option_2fa_div").css("display", "none");
84
  jQuery("#custom_form_2fa_div").css("display", "none");
85
  jQuery("#video_guide_2fa_div").css("display", "none");
87
  jQuery("#setup_2fa").addClass("active");
88
  function openTab2fa(elmt){
89
  var tabname = elmt.id;
90
+ var tabarray = ["setup_2fa","rba_2fa","custom_login_2fa","shortcode_2fa","login_option_2fa", "custom_form_2fa", "video_guide_2fa","unlimittedUser_2fa"];
91
  for (var i = 0; i < tabarray.length; i++) {
92
  if(tabarray[i] == tabname){
93
  jQuery("#"+tabarray[i]).addClass("active");
99
  }
100
  localStorage.setItem("lastTab2fa", tabname);
101
  }
102
+ var tab = localStorage.getItem("lastTab2fa");
103
+ var is_onprem = '<?php echo MO2F_IS_ONPREM;?>';
104
  if(tab == "setup_twofa"){
105
  document.getElementById("setup_2fa").click();
106
+ }else if(tab == "rba_2fa"){
 
 
107
  document.getElementById("rba_2fa").click();
108
  }
109
  else if(tab == "custom_login_2fa"){
113
  document.getElementById("shortcode_2fa").click();
114
  }
115
  else if(tab == "login_option_2fa"){
116
+ document.getElementById("login_option_2fa").click();
117
  }
118
  else if(tab == "custom_form_2fa"){
119
  document.getElementById("custom_form_2fa").click();
121
  else if(tab == "video_guide_2fa"){
122
  document.getElementById("video_guide_2fa").click();
123
  }
124
+ else if(tab == "unlimittedUser_2fa")
125
+ {
126
+ document.getElementById("unlimittedUser_2fa").click();
127
+ }
128
  else{
129
  document.getElementById("setup_2fa").click();
130
  }
131
+ </script>
views/twofa/two_fa_custom_form.php CHANGED
@@ -1,30 +1,97 @@
1
- <div class="mo_wpns_setting_layout">
2
  <h2>Custom Login Forms</h2>
3
  <p>We support most of the login forms present on the wordpress. And our plugin is tested with almost all the forms like Woocommerce, Ultimate Member, Restrict Content Pro and so on.</p>
4
- <ul>
5
- <form id="woocommerce_login_prompt_form" method="post">
6
- <li><?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/woocommerce.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit; padding-right: 50px;">Woocommerce</h3>
7
 
8
- <input type="checkbox" name="woocommerce_login_prompt" onchange="document.getElementById('woocommerce_login_prompt_form').submit();" <?php if(get_site_option('mo2f_woocommerce_login_prompt')){?> checked <?php } ?> <?php if(!get_site_option('mo2f_enable_2fa_prompt_on_login_page')){?> disabled <?php } ?>/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  <input type="hidden" name="option" value="woocommerce_disable_login_prompt">
10
- <b style="font-size: 130%;">Show 2FA prompt on Woocommerce Login Page.</b>
11
- <br>
12
-
13
- <b style="padding-left: 200px;color: red;" >**If you want to enable/disable 2FA prompt on other Custom login pages please Contact us.</b>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  <br>
15
- <b style="padding-left: 230px;color: red;" >**This feature will only work when you enable 2FA prompt on wordpress login page.</li></b>
 
 
16
 
17
- </form>
18
- <br>
19
- <li><?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/ultimate_member.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">Ultimate Member</h3></li><br>
20
- <li><?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/restrict_content_pro.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">Restrict Content Pro</h3></li><br>
21
- <li><?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/theme_my_login.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">My Theme Login</h3></li><br>
22
- <li><?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/user_registration.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">User Registration</h3></li><br>
23
- <li><?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/Custom_Login_Page_Customizer_LoginPress.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">Custom Login Page Customizer | LoginPress</h3></li><br>
24
- <li><?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/Admin_Custom_Login.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">Admin Custom Login</h3></li><br>
25
- <li><?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/RegistrationMagic_Custom_Registration_Forms_and_User_Login.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">RegistrationMagic – Custom Registration Forms and User Login</h3></li>
26
- </ul>
27
- <p>And many more which are not mentioned here.</p>
28
-
29
- <p style="font-size:15px">If there is any custom login form where Two Factor is not initiated you can get let us know so that we can add support for it. You can reach us by dropping a query in the <b>Support</b> section.</p>
30
- </div>
1
+ <div class="mo_wpns_setting_layout">
2
  <h2>Custom Login Forms</h2>
3
  <p>We support most of the login forms present on the wordpress. And our plugin is tested with almost all the forms like Woocommerce, Ultimate Member, Restrict Content Pro and so on.</p>
 
 
 
4
 
5
+ <div>
6
+ <table class="customloginform" style="width: 100%;" align="left">
7
+ <tr>
8
+ <th class="fontsize">
9
+ Custom Login form
10
+ </th>
11
+ <th style="width: 50%;">
12
+ Show 2FA prompt on Custom login
13
+
14
+ </th>
15
+ </tr>
16
+ <tr>
17
+ <td>
18
+ <?php echo '<img style="width:30px; height:30px;display: inline;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/woocommerce.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit; padding-right: 50px;">Woocommerce</h3>
19
+ </td>
20
+ <td style="align-items: right;width: 50%;">
21
+ <form id="woocommerce_login_prompt_form" method="post">
22
+ <div align="center">
23
+ <input type="checkbox" name="woocommerce_login_prompt" onchange="document.getElementById('woocommerce_login_prompt_form').submit();" <?php if(get_site_option('mo2f_woocommerce_login_prompt')){?> checked <?php } ?> <?php if(!get_site_option('mo2f_enable_2fa_prompt_on_login_page')){?> disabled <?php } ?>/>
24
+ </div>
25
  <input type="hidden" name="option" value="woocommerce_disable_login_prompt">
26
+
27
+ </form>
28
+ </td>
29
+ </tr>
30
+ <tr>
31
+ <td>
32
+ <?php echo '<img style="width:30px; height:30px;display: inline;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/ultimate_member.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">Ultimate Member</h3>
33
+ </td>
34
+ <td style="text-align: center;">
35
+ <input type="checkbox" name="" disabled>
36
+ </td>
37
+ </tr>
38
+ <tr>
39
+ <td>
40
+ <?php echo '<img style="width:30px; height:30px;display: inline;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/restrict_content_pro.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">Restrict Content Pro</h3>
41
+ </td>
42
+ <td style="text-align: center;">
43
+ <input type="checkbox" name="" disabled>
44
+ </td>
45
+ </tr>
46
+ <tr>
47
+ <td >
48
+ <?php echo '<img style="width:30px; height:30px;display: inline;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/theme_my_login.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">My Theme Login</h3>
49
+ </td>
50
+ <td style="text-align: center;">
51
+ <input type="checkbox" name="" disabled>
52
+ </td>
53
+ </tr>
54
+ <tr>
55
+ <td>
56
+ <?php echo '<img style="width:30px; height:30px;display: inline;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/user_registration.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">User Registration</h3>
57
+ </td>
58
+ <td style="text-align: center;">
59
+ <input type="checkbox" name="" disabled>
60
+ </td>
61
+ </tr>
62
+ <tr>
63
+ <td>
64
+ <?php echo '<img style="width:30px; height:30px;display: inline;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/Custom_Login_Page_Customizer_LoginPress.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">Custom Login Page Customizer | LoginPress</h3>
65
+ </td>
66
+ <td style="text-align: center;">
67
+ <input type="checkbox" name="" disabled>
68
+ </td>
69
+ </tr>
70
+ <tr>
71
+ <td>
72
+ <?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/Admin_Custom_Login.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">Admin Custom Login</h3>
73
+ </td>
74
+ <td style="text-align: center;">
75
+ <input type="checkbox" name="" disabled>
76
+ </td>
77
+ </tr>
78
+ <tr>
79
+ <td>
80
+ <?php echo '<img style="width:30px; height:30px;display: inline;float: left;" src="'.dirname(plugin_dir_url(dirname(__FILE__))).'/includes/images/RegistrationMagic_Custom_Registration_Forms_and_User_Login.png">';?><h3 style="margin-left: 15px; font-size: large; display: inline; float: inherit;">RegistrationMagic – Custom Registration Forms and User Login</h3>
81
+ </td>
82
+ <td style="text-align: center; ">
83
+ <input type="checkbox" name="" disabled>
84
+ </td>
85
+ </tr>
86
+
87
+ </table>
88
+ </div>
89
+ <div style="float: left;">
90
  <br>
91
+ <b style="color: red; " >**If you want to enable/disable 2FA prompt on other Custom login pages please Contact us.</b>
92
+ <br>
93
+ <b style="color: red;" >**This feature will only work when you enable 2FA prompt on wordpress login page.</li></b>
94
 
95
+ <p style="font-size:15px">If there is any custom login form where Two Factor is not initiated for you, plese reach out to us by dropping a query in the <b>Support</b> section.</p>
96
+ </div>
97
+ </div>
 
 
 
 
 
 
 
 
 
 
 
views/twofa/two_fa_custom_login.php CHANGED
@@ -11,6 +11,7 @@
11
 
12
  <h3 id="custom_description" style=" color: #20b2aa;text-align: center;">
13
  <?php echo __( 'This helps you to modify and redesign the 2FA prompt to match according to your website and various customizations in the plugin dashboard.', 'miniorange-2-factor-authentication' ); ?>
 
14
  </h3>
15
  <br>
16
  </div>
11
 
12
  <h3 id="custom_description" style=" color: #20b2aa;text-align: center;">
13
  <?php echo __( 'This helps you to modify and redesign the 2FA prompt to match according to your website and various customizations in the plugin dashboard.', 'miniorange-2-factor-authentication' ); ?>
14
+ <b style="color: red;">&nbsp;&nbsp;[ PREMIUM ]</b>
15
  </h3>
16
  <br>
17
  </div>
views/twofa/two_fa_login_option.php CHANGED
@@ -34,7 +34,7 @@ global $Mo2fdbQueries;
34
  <div style="margin-left: 2%;">
35
  <input type="radio" name="mo2f_login_option" value="1"
36
  <?php checked( get_option( 'mo2f_login_option' ) );
37
- if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
38
  } else {
39
  echo 'disabled';
40
  } ?> />
@@ -46,7 +46,7 @@ global $Mo2fdbQueries;
46
  <div style="margin-left:6%;">
47
  <input type="checkbox" id="mo2f_remember_device" name="mo2f_remember_device"
48
  value="1" <?php checked( get_option( 'mo2f_remember_device' ) == 1 );
49
- if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
50
  } else {
51
  echo 'disabled';
52
  } ?> />Enable
@@ -62,7 +62,7 @@ global $Mo2fdbQueries;
62
 
63
  <input type="radio" name="mo2f_login_option" value="0"
64
  <?php checked( ! get_option( 'mo2f_login_option' ) );
65
- if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
66
  } else {
67
  echo 'disabled';
68
  } ?> />
@@ -86,14 +86,15 @@ global $Mo2fdbQueries;
86
  <input type="checkbox" id="mo2f_login_with_username_and_2factor"
87
  name="mo2f_login_with_username_and_2factor"
88
  value="1" <?php checked( get_option( 'mo2f_enable_login_with_2nd_factor' ) == 1 );
89
- if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
90
  } else {
91
  echo 'disabled';
92
  } ?> />
93
  <?php echo mo2f_lt( ' I want to hide default login form.' ); ?> &nbsp;<a
94
-
95
  data-toggle="collapse"
96
- href="#preview8"
 
97
  aria-expanded="false"><?php echo mo2f_lt( 'See preview' ); ?></a>
98
  <br>
99
  <div class="mo2f_collapse" id="preview8" style="height:300px;">
@@ -102,6 +103,7 @@ global $Mo2fdbQueries;
102
  src="https://login.xecurify.com/moas/images/help/login-help-3.png">
103
  </center>
104
  </div>
 
105
  <br>
106
  <div class="mo2f_advanced_options_note"><p style="padding:5px;">
107
  <i><?php echo mo2f_lt( 'Checking this option will hide default login form and just show login with your phone. Click above link to see the preview.' ); ?></i>
@@ -150,7 +152,7 @@ global $Mo2fdbQueries;
150
  <div style="padding:10px;">
151
  <center>
152
  <?php
153
- if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' ) {
154
  ?>
155
  <input type="submit" name="submit" value="<?php echo mo2f_lt( 'Save Settings' ); ?>"
156
  class="mo_wpns_button mo_wpns_button1">
@@ -187,8 +189,28 @@ global $Mo2fdbQueries;
187
  jQuery('#loginphonediv').show();
188
  }
189
  });
190
-
191
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  function show_backup_options() {
193
  jQuery("#backup_options").slideToggle(700);
194
  jQuery("#login_options").hide();
@@ -279,7 +301,7 @@ function get_standard_premium_options( $user ) {
279
  <?php if ( $is_NC ) { ?>
280
  <div>
281
  <a class="mo2f_view_backup_options" onclick="show_backup_options()">
282
- <img src="<?php echo plugins_url( 'includes/images/right-arrow.png', dirname(dirname(__FILE__)) ); ?>"
283
  class="mo2f_advanced_options_images"/>
284
 
285
  <p class="mo2f_heading_style"><?php echo mo2f_lt( 'Backup Options' ); ?></p>
@@ -315,19 +337,19 @@ function get_standard_premium_options( $user ) {
315
  <div>
316
  <ul style="margin-left:4%" class="mo2f_ol">
317
  <li><?php echo mo2f_lt( 'Login with Wordpress username/password and 2nd Factor' ); ?> <a
318
- data-toggle="collapse" id="showpreview1" href="#preview7"
319
  aria-expanded="false">[ <?php echo mo2f_lt( 'See Preview' ); ?>
320
  ]</a>
321
- <div class="mo2f_collapse" id="preview7" style="height:300px;">
322
  <center><br>
323
  <img style="height:300px;"
324
  src="https://login.xecurify.com/moas/images/help/login-help-1.png">
325
  </center>
326
-
327
  </div>
 
328
  </li><br>
329
  <li><?php echo mo2f_lt( 'Login with Wordpress username and 2nd Factor only' ); ?> <a
330
- data-toggle="collapse" id="showpreview2" href="#preview6"
331
  aria-expanded="false">[ <?php echo mo2f_lt( 'See Preview' ); ?>
332
  ]</a>
333
  <br>
@@ -507,8 +529,7 @@ function get_standard_premium_options( $user ) {
507
 
508
 
509
  <div>
510
- <a class="mo2f_view_login_options" onclick="show_login_options()">
511
-
512
  <p class="mo2f_heading_style"><?php echo mo2f_lt( 'User Login Options' ); ?></p>
513
  </a>
514
  </div>
34
  <div style="margin-left: 2%;">
35
  <input type="radio" name="mo2f_login_option" value="1"
36
  <?php checked( get_option( 'mo2f_login_option' ) );
37
+ if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' or MO2F_IS_ONPREM) {
38
  } else {
39
  echo 'disabled';
40
  } ?> />
46
  <div style="margin-left:6%;">
47
  <input type="checkbox" id="mo2f_remember_device" name="mo2f_remember_device"
48
  value="1" <?php checked( get_option( 'mo2f_remember_device' ) == 1 );
49
+ if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' and MO2F_IS_ONPREM!=1) {
50
  } else {
51
  echo 'disabled';
52
  } ?> />Enable
62
 
63
  <input type="radio" name="mo2f_login_option" value="0"
64
  <?php checked( ! get_option( 'mo2f_login_option' ) );
65
+ if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' or MO2F_IS_ONPREM) {
66
  } else {
67
  echo 'disabled';
68
  } ?> />
86
  <input type="checkbox" id="mo2f_login_with_username_and_2factor"
87
  name="mo2f_login_with_username_and_2factor"
88
  value="1" <?php checked( get_option( 'mo2f_enable_login_with_2nd_factor' ) == 1 );
89
+ if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' or MO2F_IS_ONPREM ){
90
  } else {
91
  echo 'disabled';
92
  } ?> />
93
  <?php echo mo2f_lt( ' I want to hide default login form.' ); ?> &nbsp;<a
94
+ class=""
95
  data-toggle="collapse"
96
+ href="#preview9"
97
+ id = 'showpreview8'
98
  aria-expanded="false"><?php echo mo2f_lt( 'See preview' ); ?></a>
99
  <br>
100
  <div class="mo2f_collapse" id="preview8" style="height:300px;">
103
  src="https://login.xecurify.com/moas/images/help/login-help-3.png">
104
  </center>
105
  </div>
106
+
107
  <br>
108
  <div class="mo2f_advanced_options_note"><p style="padding:5px;">
109
  <i><?php echo mo2f_lt( 'Checking this option will hide default login form and just show login with your phone. Click above link to see the preview.' ); ?></i>
152
  <div style="padding:10px;">
153
  <center>
154
  <?php
155
+ if ( $mo_2factor_user_registration_status == 'MO_2_FACTOR_PLUGIN_SETTINGS' or MO2F_IS_ONPREM) {
156
  ?>
157
  <input type="submit" name="submit" value="<?php echo mo2f_lt( 'Save Settings' ); ?>"
158
  class="mo_wpns_button mo_wpns_button1">
189
  jQuery('#loginphonediv').show();
190
  }
191
  });
192
+
193
+ jQuery('#preview9').hide();
194
+ jQuery('#showpreview1').click(function(){
195
+ jQuery('#preview9').slideToggle(700);
196
+ });
197
+
198
+ jQuery('#preview7').hide();
199
+ jQuery('#showpreview7').click(function(){
200
+ jQuery('#preview7').slideToggle(700);
201
+ });
202
+
203
+ jQuery('#preview6').hide();
204
+ jQuery('#showpreview6').click(function(){
205
+ jQuery('#preview6').slideToggle(700);
206
+ });
207
+
208
+ jQuery('#preview8').hide();
209
+ jQuery('#showpreview8').click(function(){
210
+ jQuery('#preview8').slideToggle(700);
211
+ });
212
+
213
+
214
  function show_backup_options() {
215
  jQuery("#backup_options").slideToggle(700);
216
  jQuery("#login_options").hide();
301
  <?php if ( $is_NC ) { ?>
302
  <div>
303
  <a class="mo2f_view_backup_options" onclick="show_backup_options()">
304
+ <img src="<?php echo plugins_url( 'includes/images/right-arrow.png', dirname(dirname(__FILE__ ))); ?>"
305
  class="mo2f_advanced_options_images"/>
306
 
307
  <p class="mo2f_heading_style"><?php echo mo2f_lt( 'Backup Options' ); ?></p>
337
  <div>
338
  <ul style="margin-left:4%" class="mo2f_ol">
339
  <li><?php echo mo2f_lt( 'Login with Wordpress username/password and 2nd Factor' ); ?> <a
340
+ class="" data-toggle="collapse" id="showpreview7" href="#preview7"
341
  aria-expanded="false">[ <?php echo mo2f_lt( 'See Preview' ); ?>
342
  ]</a>
343
+ <div class="mo2f_collapse" id="preview7" style="height:300px;">
344
  <center><br>
345
  <img style="height:300px;"
346
  src="https://login.xecurify.com/moas/images/help/login-help-1.png">
347
  </center>
 
348
  </div>
349
+
350
  </li><br>
351
  <li><?php echo mo2f_lt( 'Login with Wordpress username and 2nd Factor only' ); ?> <a
352
+ class="" data-toggle="collapse" id="showpreview6" href="#preview6"
353
  aria-expanded="false">[ <?php echo mo2f_lt( 'See Preview' ); ?>
354
  ]</a>
355
  <br>
529
 
530
 
531
  <div>
532
+ <a class="mo2f_view_login_options" onclick="show_login_options()">
 
533
  <p class="mo2f_heading_style"><?php echo mo2f_lt( 'User Login Options' ); ?></p>
534
  </a>
535
  </div>
views/twofa/two_fa_rba.php CHANGED
@@ -2,7 +2,7 @@
2
  <form id="settings_from_addon" method="post" action="">
3
  <input type="hidden" name="option" value="mo_auth_addon_settings_save"/>
4
  <h3 id="rba_description" style="color: #20b2aa; text-align: center;">
5
- It helps you to remember the device where you will not be asked to authenticate the 2-factor if you login from the Remember Device.</h3>
6
  <br>
7
  <h3><?php echo mo2f_lt( 'Remember Device' ); ?></h3>
8
  <hr>
@@ -131,7 +131,6 @@
131
 
132
  jQuery('#mo2f_hide_rba_content').hide();
133
  jQuery('#mo2f_activate_rba_addon').hide();
134
- // jQuery('#mo2f_purchase_rba_addon').hide();
135
 
136
  </script>
137
  <?php
@@ -145,7 +144,7 @@
145
 
146
  <div>
147
  <div class="mo_wpns_setting_layout" style="background-color: aliceblue; border:none;">
148
- <h3>Remember device</h3>
149
  <input type="checkbox" id="mo2f_remember_device" name="mo2f_remember_device"
150
  value="1" <?php checked( get_option( 'mo2f_remember_device' ) == 1 );
151
 
2
  <form id="settings_from_addon" method="post" action="">
3
  <input type="hidden" name="option" value="mo_auth_addon_settings_save"/>
4
  <h3 id="rba_description" style="color: #20b2aa; text-align: center;">
5
+ It helps you to remember the device where you will not be asked to authenticate the 2-factor if you login from the remembered Device.</h3>
6
  <br>
7
  <h3><?php echo mo2f_lt( 'Remember Device' ); ?></h3>
8
  <hr>
131
 
132
  jQuery('#mo2f_hide_rba_content').hide();
133
  jQuery('#mo2f_activate_rba_addon').hide();
 
134
 
135
  </script>
136
  <?php
144
 
145
  <div>
146
  <div class="mo_wpns_setting_layout" style="background-color: aliceblue; border:none;">
147
+ <h3>Remember device<b style="color: red;">&nbsp;&nbsp;&nbsp;&nbsp;[ PREMIUM ]</b></h3>
148
  <input type="checkbox" id="mo2f_remember_device" name="mo2f_remember_device"
149
  value="1" <?php checked( get_option( 'mo2f_remember_device' ) == 1 );
150
 
views/twofa/two_fa_setup_notification.php CHANGED
@@ -3,7 +3,14 @@
3
  function mo2f_display_test_2fa_notification( $user ) {
4
  global $Mo2fdbQueries;
5
  $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
 
 
 
6
 
 
 
 
 
7
  ?>
8
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
9
  <div id="twoFAtestAlertModal" class="modal" role="dialog">
3
  function mo2f_display_test_2fa_notification( $user ) {
4
  global $Mo2fdbQueries;
5
  $mo2f_configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
6
+
7
+ if(MO2F_IS_ONPREM)
8
+ {
9
 
10
+ $mo2f_configured_2FA_method = get_user_meta($user->ID,'currentMethod',true);
11
+ update_user_meta($user->ID,$mo2f_configured_2FA_method,1);
12
+
13
+ }
14
  ?>
15
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
16
  <div id="twoFAtestAlertModal" class="modal" role="dialog">
views/twofa/two_fa_shortcode.php CHANGED
@@ -7,7 +7,7 @@
7
 
8
 
9
  <div id="mo2f_hide_shortcode_content" >
10
- <h3><?php echo __( 'List of Shortcodes', 'miniorange-2-factor-authentication' ); ?>:</h3>
11
  <hr>
12
  <ol style="margin-left:2%">
13
  <li>
@@ -36,10 +36,9 @@
36
  <form name="f" id="custom_login_form" method="post" action="">
37
  <?php echo mo2f_lt('Enter the id of your custom login form to use \'Enable Remember Device\' on the login page:');?>
38
  <input type="text" class="mo2f_table_textbox" id="mo2f_rba_loginform_id"
39
- name="mo2f_rba_loginform_id" <?php if (mo2f_is_customer_registered()) {
40
- } else {
41
  echo 'disabled';
42
- } ?> value="<?php echo get_option('mo2f_rba_loginform_id') ?>"/>
43
  <br><br>
44
  <input type="hidden" name="option" value="custom_login_form_save"/>
45
  <input type="submit" name="submit" value="Save Settings" style="background-color: #20b2aa; color: white;" class="mo_wpns_button mo_wpns_button1" <?php
7
 
8
 
9
  <div id="mo2f_hide_shortcode_content" >
10
+ <h3><?php echo __( 'List of Shortcodes', 'miniorange-2-factor-authentication' ); ?><b style="color: red;">&nbsp;&nbsp;&nbsp;&nbsp;[ PREMIUM ]</b></h3>
11
  <hr>
12
  <ol style="margin-left:2%">
13
  <li>
36
  <form name="f" id="custom_login_form" method="post" action="">
37
  <?php echo mo2f_lt('Enter the id of your custom login form to use \'Enable Remember Device\' on the login page:');?>
38
  <input type="text" class="mo2f_table_textbox" id="mo2f_rba_loginform_id"
39
+ name="mo2f_rba_loginform_id" <?php
 
40
  echo 'disabled';
41
+ ?> value="<?php echo get_option('mo2f_rba_loginform_id') ?>"/>
42
  <br><br>
43
  <input type="hidden" name="option" value="custom_login_form_save"/>
44
  <input type="submit" name="submit" value="Save Settings" style="background-color: #20b2aa; color: white;" class="mo_wpns_button mo_wpns_button1" <?php
views/twofa/two_fa_unlimittedUser.php ADDED
@@ -0,0 +1,697 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function miniorange_2_factor_user_roles($current_user) {
4
+
5
+ global $wp_roles;
6
+ if (!isset($wp_roles))
7
+ $wp_roles = new WP_Roles();
8
+
9
+ print '<div><span style="font-size:16px;">Roles<div style="float:right;">Custom Redirect Login Url <b style = "color:red"> [PREMIUM] </b> </div></span><br /><br />';
10
+ foreach($wp_roles->role_names as $id => $name) {
11
+ $setting = get_site_option('mo2fa_'.$id);
12
+ ?>
13
+ <div>
14
+ <input type="checkbox" name="role" value="<?php echo 'mo2fa_'.$id; ?>"
15
+ <?php
16
+ if($id=='administrator'){
17
+ if(get_site_option('mo2fa_administrator'))
18
+ echo 'checked' ;
19
+ else{
20
+ echo 'unchecked';
21
+ }
22
+ }
23
+ else{
24
+ echo 'disabled' ;
25
+ }
26
+ ?>/>
27
+ <?php
28
+ echo $name;
29
+ if($name != 'Administrator')
30
+ echo " <b style='color:red;padding-left:10px;'> [PREMIUM] </b>";
31
+ ?>
32
+ <input type="text" class="mo2f_table_textbox" style="width:50% !important;float:right;" id="<?php echo 'mo2fa_'.$id; ?>_login_url" value="<?php echo get_option('mo2fa_' .$id . '_login_url'); ?>"
33
+ <?php
34
+ echo 'disabled' ;
35
+ ?>
36
+ />
37
+ </div>
38
+ <br/>
39
+ <?php
40
+ }
41
+ print '</div>';
42
+ }
43
+ $user = wp_get_current_user();
44
+ $configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
45
+ $configured_meth = array();
46
+ $configured_meth = array('Email Verification','Google Authenticator','Security Questions','Authy Authenticator');
47
+ $method_exisits = in_array($configured_2FA_method, $configured_meth);
48
+ ?>
49
+ <?php
50
+ if(current_user_can('administrator')){
51
+ ?>
52
+ <div class="mo_wpns_setting_layout">
53
+ <h3>Enable/disable 2-factor Authentication</h3>
54
+ <hr>
55
+ <div style="padding-top: 1%;">
56
+ <form name="f" method="post" action="" >
57
+ <input type="hidden" id="mo2f_nonce_enable_2FA" name="mo2f_nonce_enable_2FA"
58
+ value="<?php echo wp_create_nonce( "mo2f-nonce-enable-2FA" ) ?>"/>
59
+
60
+ <input type="checkbox" onChange="mo_toggle_twofa()" style="padding-top: 50px;" id="mo2f_enable_2faa"
61
+ name="mo2f_enable_2fa"
62
+ value="<?php get_option( 'mo2f_activate_plugin' ) ?>"<?php checked( get_option( 'mo2f_activate_plugin' ) == 1 );?>/>
63
+ <?php
64
+ echo mo2f_lt( 'Enable Two-Factor plugin.' );
65
+ ?>
66
+ <div style="padding-top: 1%;">
67
+ <b style="color: red;"> NOTE : If you disable this checkbox, Two-Factor will not be invoked for any user during login.</b>
68
+ </div>
69
+ </form>
70
+ </div>
71
+ </div>
72
+ <script type="text/javascript">
73
+ function mo_toggle_twofa(){
74
+ var data = {
75
+ 'action' : 'mo_two_factor_ajax',
76
+ 'mo_2f_two_factor_ajax' : 'mo2f_enable_disable_twofactor',
77
+ 'mo2f_nonce_enable_2FA' : jQuery('#mo2f_nonce_enable_2FA').val(),
78
+ 'mo2f_enable_2fa' : jQuery('#mo2f_enable_2faa').is(":checked"),
79
+ };
80
+ jQuery.post(ajaxurl, data, function(response) {
81
+ var response = response.replace(/\s+/g,' ').trim();
82
+ if (response == "true"){
83
+ jQuery('#mo_scan_message').empty();
84
+ jQuery('#mo_scan_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp&nbsp Two factor is now enabled.</div></div>");
85
+ window.onload = nav_popup();
86
+ }
87
+ else{
88
+ jQuery('#mo_scan_message').empty();
89
+ jQuery('#mo_scan_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp&nbsp Two factor is now disabled.</div></div>");
90
+ window.onload = nav_popup();
91
+ }
92
+ });
93
+
94
+ }
95
+ </script>
96
+ <?php
97
+ }
98
+
99
+ if(MO2F_IS_ONPREM && current_user_can('administrator'))
100
+ {
101
+ ?>
102
+ <div class="mo_wpns_setting_layout" id="2fa_method">
103
+ <input type="hidden" name="option" value="" />
104
+ <span>
105
+ <h3>Select Roles to enable 2-Factor for Users <b style="font-size: 70%;color: red;">(Upto 5 users in Free version)</b></h3>
106
+ <span>
107
+ <hr><br>
108
+
109
+ <?php
110
+ echo miniorange_2_factor_user_roles($current_user);
111
+ ?>
112
+ <br>
113
+ </span>
114
+ <input type="submit" id="save_role_2FA" name="submit" value="Save Settings" class="mo_wpns_button mo_wpns_button1" />
115
+ </span>
116
+ <br><br>
117
+ <div id="mo2f_note">
118
+ <b>Note:</b> Selecting the above roles will enable 2-Factor for all users associated with that role.
119
+ </div>
120
+ </div>
121
+
122
+
123
+ <script>
124
+ jQuery("#save_role_2FA").click(function(){
125
+ var enabledrole = [];
126
+ $.each($("input[name='role']:checked"), function(){
127
+ enabledrole.push($(this).val());
128
+ });
129
+ var mo2fa_administrator_login_url = $('#mo2fa_administrator_login_url').val();
130
+ var nonce = '<?php echo wp_create_nonce("unlimittedUserNonce");?>';
131
+ var data = {
132
+ 'action' : 'mo_two_factor_ajax',
133
+ 'mo_2f_two_factor_ajax' : 'mo2f_role_based_2_factor',
134
+ 'nonce' : nonce,
135
+ 'enabledrole' : enabledrole,
136
+ 'mo2fa_administrator_login_url' : mo2fa_administrator_login_url
137
+ };
138
+ jQuery.post(ajaxurl, data, function(response) {
139
+ var response = response.replace(/\s+/g,' ').trim();
140
+ if (response == "true"){
141
+ jQuery('#mo_scan_message').empty();
142
+ jQuery('#mo_scan_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp&nbsp Settings are saved.</div></div>");
143
+ window.onload = nav_popup();
144
+ }
145
+ });
146
+ });
147
+ </script>
148
+
149
+ <?php
150
+ }
151
+
152
+
153
+ if(!MO2F_IS_ONPREM && current_user_can('administrator')){
154
+ ?>
155
+ <div id="wpns_message" >
156
+ </div>
157
+ <div class="mo_wpns_setting_layout" id="onpremisediv">
158
+ <p class="modal-body-para" style="text-align: center;">
159
+ <b>Two-Factor Authentication for Multiple Users<span style="color: red;"> [No Payment Needed]</span></b>
160
+ </p>
161
+ <hr>
162
+ <p class="modal-body-para">
163
+ <span style="font-size: 15px;">
164
+ <b>Current Solution</b>
165
+ </span>
166
+ <ul style="list-style-type:disc; padding-left: 5%;">
167
+ <li style="font-size: 15px;">You are currently using a Cloud Solution for 2-factor Authentication</li>
168
+ <li style="font-size: 15px;">In this solution miniOrange provides you 2-factor authentication free only for one user.</li>
169
+ </ul>
170
+ <br>
171
+ <span style="font-size: 15px;">
172
+ <b>2FA For Multiple User</b>
173
+ </span>
174
+ <ul style="list-style-type:disc; padding-left: 5%;">
175
+ <li style="font-size: 15px;">If you want to use 2-factor authentication for multiple users, you need to enable the Wordpress Solution [On-Premise 2-factor Authentication].</li>
176
+ <li style="font-size: 15px;">You can get two-factor authentication <b>FREE</b> for all <u>Administrators</u>.</li>
177
+ <li style="font-size: 15px;">By clicking the button below all dependecies will be shifted to wordpress [On-Premise Solution] and there will be no inclusion of any 3rd party not even miniOrange so this will increase the process speed for authentication.</li>
178
+ </ul>
179
+ <br>
180
+ <span style="font-size: 15px;color: red;">
181
+ <b>Not Supported in Wordpress Solution [On-Premise Solution]</b>
182
+ </span>
183
+ <ul style="list-style-type:disc; padding-left: 5%;">
184
+ <li style="font-size: 15px;"><b>2FA Methods</b></li>
185
+ </ul>
186
+ <div style="padding-left: 10%;">
187
+ <ul style="font-size: 15px; list-style-type:circle;">
188
+ <?php
189
+ if (get_site_option('mo2f_is_NC') == 0) {
190
+ ?>
191
+ <li>OTP Over SMS</li>
192
+ <?php
193
+ }
194
+ ?>
195
+ <li>miniOrange QR Code Authentication</li>
196
+ <li>miniOrange Soft Token</li>
197
+ <li>miniOrange Push Notification</li>
198
+ </ul>
199
+ </div>
200
+ <ul style="list-style-type:disc; padding-left: 5%;">
201
+ <li style="font-size: 15px;"><b>Remember Device</b></li>
202
+ <li style="font-size: 15px;"><b>XML-RPC Login</b></li>
203
+ </ul>
204
+ </p>
205
+ <strong style="color: #ff0000">[Note]: By enabling this you will have to reconfigure the second factor and all configuration of previous account will be deleted.</strong>
206
+ <p class="modal-body-para" style="font">
207
+ <h2 style="text-align: center;"> Enable Two-Factor for all Users
208
+ <label class='mo_wpns_switch' >
209
+ <input type="checkbox" name="unlimittedUser" id="unlimittedUser"/>
210
+ <span class='mo_wpns_slider mo_wpns_round'></span>
211
+ </label>
212
+ </h2>
213
+ <hr>
214
+ <p><i class="mo_wpns_not_bold"><h4> <strong style="color: #ff0000">[WARNING]: </strong> This will disconfigure the two-factor for the current account and you need to configure it again. By enabling it you will not be able to use the cloud solution again.</h4> </i></p>
215
+ </p>
216
+
217
+
218
+ <?php
219
+ ?>
220
+ </div>
221
+ <div id="ConfirmOnPrem" class="modal">
222
+ <!-- Modal content -->
223
+ <div class="modal-content">
224
+ <!-- <span class="close">&times;</span> -->
225
+ <div class="modal-header">
226
+ <h3 class="modal-title" style="text-align: center; font-size: 20px; color: #ff0000">WARNING</h3>
227
+ <p class="modal-body-para">
228
+ <?php if($method_exisits && $configured_2FA_method != '' ){
229
+ if ($configured_2FA_method=='Email Verification') {
230
+ ?>
231
+ <div style="text-align: center; font-size: 130%;">
232
+ Current 2FA method:- <b><?php echo $configured_2FA_method ?></b>
233
+ <hr>
234
+ <ul style="list-style-type:circle;font-size: 14px">
235
+ <li style="text-align: left;">This 2FA method is available in Wordpress Solution.</li>
236
+ </ul>
237
+
238
+ </div>
239
+ <?php
240
+ }
241
+ elseif ($configured_2FA_method == 'Authy Authenticator')
242
+ {
243
+ ?>
244
+ Current 2FA method:- <b><?php echo $configured_2FA_method ?></b>
245
+ <hr>
246
+ <ul style="list-style-type:circle;font-size: 14px;text-align: left;">
247
+ <li>Authy Authenticator and Google Authenticator are same in the wordpress Solution.</li>
248
+ <li>You will need to reconfigure it if you want to proceed with Wordpress Solution.</li>
249
+ </ul>
250
+ <?php
251
+ }
252
+ else
253
+ {
254
+ ?>
255
+ Current 2FA method:- <b><?php echo $configured_2FA_method ?></b>
256
+ <hr>
257
+ <ul style="list-style-type:circle;font-size: 14px;text-align: left;">
258
+ <li>You will need to reconfigure it if you want to proceed with Wordpress Solution.</li>
259
+ </ul>
260
+ <?php
261
+ }
262
+ if (get_option( 'mo2f_remember_device' )) {
263
+ ?> <ul style="list-style-type:circle;font-size: 14px;text-align: left;">
264
+ <li><b style="color:red;">your remember device is on, which is not supported in wordpress solution.</b></li>
265
+ </ul>
266
+ <?php
267
+ }
268
+ }
269
+ else if($configured_2FA_method != ''){
270
+ ?>
271
+ Current 2FA method:- <b><?php echo $configured_2FA_method ?></b>
272
+ <hr>
273
+ <p>
274
+ <ul style="list-style-type:circle;font-size: 14px;text-align: left;">
275
+ <li>This method is <b> not supported </b> in Wordpress Solution[On-Premise Solution]</li>
276
+ <br>
277
+ <li><b>You can still use other 2FA methods for multiple users by clicking on confirm.</b> </li>
278
+ <?php
279
+ if (get_option( 'mo2f_remember_device' )) {
280
+ ?> <br>
281
+ <li><b style="color:red;">your remember device is on, which is not supported in wordpress solution.</b></li></ul></p>
282
+ <?php
283
+ }
284
+
285
+ }
286
+ else{
287
+ ?>
288
+ We support only the following 2-Factor Authentication methods in Wordpress Solution.
289
+ <br>
290
+ <li>Google Authentication</li>
291
+ <li>Security Questions</li>
292
+ <?php if(get_site_option('mo2f_is_NC') == 0){ ?>
293
+ <li>Email Verification</li>
294
+ <?php }
295
+
296
+ }
297
+
298
+ ?>
299
+ </p>
300
+
301
+ <span id="closeConfirmOnPrem" class="modal-span-close">X</span>
302
+ </div>
303
+ <div class="modal-body_multi_user" style="height: auto">
304
+
305
+ </div>
306
+ <div class="modal-footer">
307
+ <button type="button" class="mo_wpns_button mo_wpns_button1 modal-button" style="width: 40%;" id="ConfirmOnPremButton">Confirm</button>
308
+
309
+ </div>
310
+ </div>
311
+ </div>
312
+
313
+ <div id="afterMigrate" class="modal" style="display: none;" fixed>
314
+ <div class="modal-content" style="width: 80%;overflow: hidden;" >
315
+
316
+ <div class="modal-header">
317
+ <h3 class="modal-title" style="text-align: center; font-size: 20px; color: #2980b9">
318
+ Select a method to set as your 2nd factor.
319
+ </h3>
320
+ </div>
321
+
322
+ <div class="modal-body_multi_user" fixed>
323
+ <?php
324
+ $user = wp_get_current_user();
325
+ $configured_2FA_method = $Mo2fdbQueries->get_user_detail( 'mo2f_configured_2FA_method', $user->ID );
326
+ $configured_meth = array();
327
+ if(get_site_option('mo2f_is_NC') == 0)
328
+ {
329
+ $configured_meth = array('Email Verification','Google Authenticator','Security Questions','Authy Authenticator');
330
+ }
331
+ else
332
+ {
333
+ $configured_meth = array('Google Authenticator','Security Questions','Authy Authenticator');
334
+ }
335
+ $method_exisits = in_array($configured_2FA_method, $configured_meth);
336
+ ?>
337
+ <p class="modal-body-para">
338
+ <?php
339
+ if($method_exisits){
340
+ ?>
341
+ <p class="modal-body-para">
342
+ Your Current 2FA method : <b> <?php echo $configured_2FA_method ?></b>
343
+
344
+ <p class="modal-body-para" style="font-size: 12px;color:#FF0000;padding-top: -5px;" >
345
+ <?php
346
+ if ($configured_2FA_method == 'Email Verification') {?>
347
+ <b>Please Reconfigure your Email ID.</b>
348
+
349
+ <?php }
350
+ else
351
+ {
352
+ ?>
353
+ <b>In order to continue using <?php echo $configured_2FA_method ?> as your 2nd factor for authentication, You will need to reconfigure it
354
+ </b>
355
+ <?php
356
+ }
357
+ ?>
358
+ </p>
359
+ <hr>
360
+
361
+
362
+ <div id="reconfig">
363
+ <?php if($configured_2FA_method == 'Google Authenticator'){
364
+ echo '
365
+
366
+ <button class="mo_wpns_button mo_wpns_button1" style="width:100%;" onclick ="reconfigGA()" >Click here to Reconfigure <b style="font-weight: 700;">Google/Authy/LassPass Authenticator</b> </button>
367
+ ';
368
+ }
369
+ else if($configured_2FA_method == 'Email Verification'){
370
+ $email = $user->user_email;
371
+
372
+ echo "<div>
373
+ <input type ='email' id='emalEntered' name='emalEntered' size= '50' required value=".$email.">";
374
+
375
+ echo '<span style="display:inline;"><input type="submit" id="save_email" name="" class="mo_wpns_button mo_wpns_button1" value="Save Email"></span></div>';
376
+
377
+
378
+ }
379
+ else if($configured_2FA_method == 'Security Questions'){
380
+ echo '
381
+ <button class="mo_wpns_button mo_wpns_button1" style="width:100%;" onclick ="reconfigKBA()" >Click here to Reconfigure <b style="font-weight: 700;">Security Questions</b> </button>
382
+ ';
383
+ }
384
+
385
+ ?>
386
+
387
+ </div>
388
+ </p>
389
+ <div id="reconfigTable">
390
+ <p class="modal-body-para">
391
+ The following are the other 2-Factor Authentication methods that are available in the Wordpress[On-Premise] version.
392
+ </p>
393
+ <div>
394
+ <?php
395
+
396
+
397
+ foreach($configured_meth as $value){
398
+ if($value != $configured_2FA_method ){
399
+ if($value == 'Security Questions'){
400
+ echo '
401
+ <button class="mo_wpns_button mo_wpns_button1" style="width:100%;" onclick ="reconfigKBA()" >Click here to Configure <b style="font-weight: 700;">Security Questions</b> </button>
402
+ ';
403
+ }
404
+ else if($value == 'Email Verification' ){
405
+ echo '
406
+ <button class="mo_wpns_button mo_wpns_button1" style="width:100%;" onclick ="emailVerification()" >Click here to Configure <b style="font-weight: 700;">Email Verification</b> </button>
407
+
408
+ ';
409
+ }
410
+ else if($value == 'Google Authenticator'){
411
+ echo '
412
+
413
+ <button class="mo_wpns_button mo_wpns_button1" style="width:100%;" onclick ="reconfigGA()" >Click here to Configure <b style="font-weight: 700;">Google/Authy/LassPass Authenticator </b></button>
414
+ ';
415
+ }
416
+ }
417
+ echo "<br>";
418
+ }
419
+
420
+ ?>
421
+ </div>
422
+ </div>
423
+ <center>
424
+ <table id="Emailreconfig" style="display: none;" >
425
+ <tr>
426
+ <td>
427
+ <b>Enter Your email that you will use as your 2nd factor.</b>
428
+ </td>
429
+ </tr>
430
+
431
+ <tr>
432
+ <td>
433
+ <input type="text" name="" value="" id="emalEntered" />
434
+ </td>
435
+ </tr>
436
+
437
+ <tr>
438
+ <td>
439
+ <input type="submit" id="save_email" name="" class="mo_wpns_button mo_wpns_button1" value="Save Email">
440
+
441
+ <input type="button" id="emailBack" value="Back" class="mo_wpns_button mo_wpns_button1" />
442
+ </td>
443
+ </tr>
444
+ </table>
445
+ </center>
446
+ <?php
447
+ }
448
+
449
+ else{
450
+
451
+
452
+ if($configured_2FA_method == 'NONE')
453
+ {
454
+
455
+ }
456
+ ?>
457
+
458
+
459
+
460
+
461
+ <div class="modal-body_multi_user" fixed>
462
+ <p class="modal-body-para">
463
+ <?php
464
+ if($configured_2FA_method != ''){
465
+ ?>
466
+ Your Current 2FA method : <b> <?php echo $configured_2FA_method ?></b>
467
+
468
+
469
+
470
+ <p class="modal-body-para" style="font-size: 12px;color:#FF0000;padding-top: -5px;" >
471
+ <b>
472
+ <?php echo $configured_2FA_method ?> is not supported for Multiple users, please choose some other method as your 2 factor.
473
+ </b>
474
+ </p>
475
+ <hr>
476
+ <?php }
477
+ else{
478
+ echo "";
479
+
480
+ }
481
+
482
+ ?>
483
+ <div id="msg">
484
+ <p class="modal-body-para">
485
+ The following 2-Factor Authentication methods are available in the Wordpress[On-Premise] version.
486
+ </p>
487
+ <?php
488
+ echo '
489
+
490
+ <button class="mo_wpns_button mo_wpns_button1" id="google_auth" style="width:100%;" onclick ="reconfigGA()" >Click here to Configure <b style="font-weight: 700;">Google/Authy/LassPass Authenticator</b> </button>
491
+ ';
492
+ echo "<br>";
493
+ if(get_site_option('mo2f_is_NC') == 0)
494
+ { ?>
495
+ <button class="mo_wpns_button mo_wpns_button1" style="width:100%;" onclick ="emailVerification()" >Click here to Configure <b style="font-weight: 700;">Email Verification</b> </button>
496
+ <?php }
497
+ ?>
498
+
499
+ <?php
500
+ echo "<br>";
501
+ echo '
502
+ <button class="mo_wpns_button mo_wpns_button1" id="secu_que" style="width:100%;" onclick ="reconfigKBA()" >Click here to Configure <b style="font-weight: 700;">Security Questions</b> </button>
503
+ ';
504
+ ?>
505
+ </div>
506
+ <center>
507
+ <table id="Emailreconfig" style="display: none;">
508
+ <tr>
509
+ <td>
510
+ <b>Enter Your email that you will use as your 2nd factor.</b>
511
+ </td>
512
+ </tr>
513
+
514
+ <tr>
515
+ <td>
516
+ <input type="text" name="" value="" id="emalEntered" />
517
+ </td>
518
+ </tr>
519
+
520
+ <tr>
521
+ <td>
522
+ <input type="submit" id="save_email" name="" class="mo_wpns_button mo_wpns_button1" value="Save Email">
523
+
524
+ <input type="button" id="emailBack" value="Back" class="mo_wpns_button mo_wpns_button1" />
525
+ </td>
526
+ </tr>
527
+ </table>
528
+ </center>
529
+ </div>
530
+
531
+
532
+ <?php }
533
+ ?>
534
+
535
+ </p>
536
+ </div>
537
+ </div>
538
+ </div>
539
+
540
+ <script type="text/javascript">
541
+
542
+ function reconfigKBA(){
543
+ var data = {
544
+ 'action' : 'mo_two_factor_ajax',
545
+ 'mo_2f_two_factor_ajax' : 'mo2f_shift_to_onprem',
546
+ };
547
+ jQuery.post(ajaxurl, data, function(response) {
548
+
549
+ if(response == 'true'){
550
+
551
+ jQuery('#mo2f_configured_2FA_method_free_plan').val('SecurityQuestions');
552
+ jQuery('#mo2f_selected_action_free_plan').val('configure2factor');
553
+ jQuery('#mo2f_save_free_plan_auth_methods_form').submit();
554
+ openTab2fa(setup_2fa);
555
+ }
556
+ });
557
+ }
558
+ function reconfigGA(){
559
+
560
+ var data = {
561
+ 'action' : 'mo_two_factor_ajax',
562
+ 'mo_2f_two_factor_ajax' : 'mo2f_shift_to_onprem',
563
+ };
564
+ jQuery.post(ajaxurl, data, function(response) {
565
+
566
+ if(response == 'true'){
567
+ jQuery('#mo2f_configured_2FA_method_free_plan').val('GoogleAuthenticator');
568
+ jQuery('#mo2f_selected_action_free_plan').val('configure2factor');
569
+ jQuery('#mo2f_save_free_plan_auth_methods_form').submit();
570
+ openTab2fa(setup_2fa);
571
+ }
572
+ });
573
+ }
574
+
575
+ function emailVerification(){
576
+ jQuery('#reconfigTable').hide();
577
+ jQuery('#Emailreconfig').show();
578
+ jQuery('#reconfig').hide();
579
+ jQuery('#msg').hide();
580
+ }
581
+ </script>
582
+
583
+ <script type="text/javascript">
584
+
585
+ jQuery('#closeConfirmOnPrem').click(function(){
586
+ document.getElementById('unlimittedUser').checked = false;
587
+ close_modal();
588
+ });
589
+ jQuery('#ConfirmOnPremButton').click(function(){
590
+ jQuery('#ConfirmOnPrem').hide();
591
+ var enableOnPremise = jQuery("input[name='unlimittedUser']:checked").val();
592
+ var nonce = '<?php echo wp_create_nonce("unlimittedUserNonce");?>';
593
+ var data = {
594
+ 'action' : 'mo_two_factor_ajax',
595
+ 'mo_2f_two_factor_ajax' : 'mo2f_unlimitted_user',
596
+ 'nonce' : nonce,
597
+ 'enableOnPremise' : enableOnPremise
598
+ };
599
+ jQuery.post(ajaxurl, data, function(response) {
600
+ var response = response.replace(/\s+/g,' ').trim();
601
+ if(response =='OnPremiseActive')
602
+ {
603
+ jQuery('#wpns_message').empty();
604
+ jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; '> Congratulations! Now you can use 2-factor Authentication for your administrators for free. ");
605
+
606
+ jQuery('#onpremisediv').hide();
607
+ jQuery('#afterMigrate').show();
608
+ }
609
+ else if(response =='OnPremiseDeactive')
610
+ {
611
+ jQuery('#wpns_message').empty();
612
+ jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; '> Cloud Solution deactivated");
613
+ close_modal();
614
+ }
615
+ else
616
+ {
617
+ jQuery('#wpns_message').empty();
618
+ jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; '> An Unknown Error has occured. ");
619
+ close_modal();
620
+ }
621
+ });
622
+
623
+ });
624
+
625
+ jQuery('#emailBack').click(function(){
626
+ jQuery('#reconfigTable').show();
627
+ jQuery('#Emailreconfig').hide();
628
+ jQuery('#msg').show();
629
+ jQuery('#reconfig').show();
630
+ });
631
+ jQuery('#save_email').click(function(){
632
+ var email = jQuery('#emalEntered').val();
633
+ var nonce = '<?php echo wp_create_nonce('EmailVerificationSaveNonce');?>';
634
+ var user_id = '<?php echo get_current_user_id();?>';
635
+
636
+ if(email != '')
637
+ {
638
+ var data = {
639
+ 'action' : 'mo_two_factor_ajax',
640
+ 'mo_2f_two_factor_ajax' : 'mo2f_save_email_verification',
641
+ 'nonce' : nonce,
642
+ 'email' : email,
643
+ 'user_id' : user_id
644
+ };
645
+ jQuery.post(ajaxurl, data, function(response) {
646
+
647
+ var response = response.replace(/\s+/g,' ').trim();
648
+ if(response=="settingsSaved")
649
+ {
650
+ jQuery('#mo2f_configured_2FA_method_free_plan').val('EmailVerification');
651
+ jQuery('#mo2f_selected_action_free_plan').val('select2factor');
652
+ jQuery('#mo2f_save_free_plan_auth_methods_form').submit();
653
+ }
654
+ else if(response == "NonceDidNotMatch")
655
+ {
656
+ //error while saving
657
+ jQuery('#mo_scan_message').empty();
658
+ jQuery('#mo_scan_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'> There were some issues. Please try again.</div></div>");
659
+ window.onload = nav_popup();
660
+
661
+ close_modal();
662
+
663
+ }
664
+ else
665
+ {
666
+ //invalid email
667
+
668
+ jQuery('#mo_scan_message').empty();
669
+ jQuery('#mo_scan_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>Please enter a valid Email.</div></div>");
670
+ window.onload = nav_popup();
671
+
672
+
673
+ }
674
+ //close_modal();
675
+ });
676
+ }
677
+ });
678
+ jQuery('#closeConfirmOnPrem').click(function(){
679
+ close_modal();
680
+ window.location.reload();
681
+ });
682
+
683
+ jQuery('#unlimittedUser').click(function(){
684
+ jQuery('#ConfirmOnPrem').css('display', 'block');
685
+ jQuery('.modal-content').css('width', '35%');
686
+
687
+ });
688
+
689
+
690
+ </script>
691
+ <script type="text/javascript">
692
+
693
+ </script>
694
+
695
+ <?php
696
+ }
697
+ ?>
views/upgrade.php CHANGED
@@ -4,7 +4,7 @@
4
  $is_NC = get_option( 'mo2f_is_NC' );
5
 
6
  $is_customer_registered = $Mo2fdbQueries->get_user_detail( 'user_registration_with_miniorange', $user->ID ) == 'SUCCESS' ? true : false;
7
-
8
  $mo2f_feature_set = array(
9
  "Authentication Methods",
10
  "No. of Users",
@@ -56,7 +56,7 @@
56
  array_slice( $two_factor_methods, 0, 11 )
57
  ),
58
  "No. of Users" => array(
59
- "1",
60
  "User Based Pricing",
61
  "User Based Pricing",
62
  "User Based Pricing"
@@ -104,7 +104,7 @@
104
  array_slice( $two_factor_methods, 0, 11 )
105
  ),
106
  "No. of Users" => array(
107
- "1",
108
  "User Based Pricing",
109
  "User Based Pricing",
110
  "User Based Pricing"
4
  $is_NC = get_option( 'mo2f_is_NC' );
5
 
6
  $is_customer_registered = $Mo2fdbQueries->get_user_detail( 'user_registration_with_miniorange', $user->ID ) == 'SUCCESS' ? true : false;
7
+ $noOfUsers= MO2F_VERSION ? "3" : "1";
8
  $mo2f_feature_set = array(
9
  "Authentication Methods",
10
  "No. of Users",
56
  array_slice( $two_factor_methods, 0, 11 )
57
  ),
58
  "No. of Users" => array(
59
+ $noOfUsers,
60
  "User Based Pricing",
61
  "User Based Pricing",
62
  "User Based Pricing"
104
  array_slice( $two_factor_methods, 0, 11 )
105
  ),
106
  "No. of Users" => array(
107
+ $noOfUsers,
108
  "User Based Pricing",
109
  "User Based Pricing",
110
  "User Based Pricing"
views/waf-settings.php CHANGED
@@ -24,7 +24,7 @@
24
  <div class="mo_wpns_setting_layout">
25
  <table style="width:100%">
26
  <tr><th align="left">
27
- <h3>Website firewall on plugin level:
28
  <br>
29
  <p><i class="mo_wpns_not_bold">This will activate WAF on plugin level. The Firewall will work after WordPress get loaded. This will check Every Request before the load of plugin.</i></p>
30
  </th><th align="right">
@@ -35,7 +35,7 @@
35
  </tr></th>
36
  </h3>
37
  <tr><th align="left">
38
- <h3>Website firewall on .htaccess level:
39
  <br>
40
  <p><i class="mo_wpns_not_bold">This will activate WAF on htaccess level. The Firewall will work before wordpress load. It will make changes to your .htaccess file.<strong> It is the recommended type</strong></i></p>
41
  </th><th align="right">
24
  <div class="mo_wpns_setting_layout">
25
  <table style="width:100%">
26
  <tr><th align="left">
27
+ <h3>Website Firewall on Plugin Level:
28
  <br>
29
  <p><i class="mo_wpns_not_bold">This will activate WAF on plugin level. The Firewall will work after WordPress get loaded. This will check Every Request before the load of plugin.</i></p>
30
  </th><th align="right">
35
  </tr></th>
36
  </h3>
37
  <tr><th align="left">
38
+ <h3>Website Firewall on .htaccess Level:
39
  <br>
40
  <p><i class="mo_wpns_not_bold">This will activate WAF on htaccess level. The Firewall will work before wordpress load. It will make changes to your .htaccess file.<strong> It is the recommended type</strong></i></p>
41
  </th><th align="right">
views/waf.php CHANGED
@@ -3,7 +3,6 @@
3
  <div class="mo_wpns_tab">
4
  <button class="tablinks" onclick="waf_function(event, 'waf_dash')" id="defaultOpen">Firewall Dashboard</button>
5
  <button class="tablinks" onclick="waf_function(event, 'settings')" id="settingsTab">Settings</button>
6
- <button class="tablinks" onclick="waf_function(event, 'block_list')" id="BlockWhiteTab" >IP Black list</button>
7
  <button class="tablinks" onclick="waf_function(event, 'real_time')" id="RealTimeTab">Real Time Blocking</button>
8
  <button class="tablinks" onclick="waf_function(event, 'rate_limiting')" id="RateLimitTab">Rate Limiting</button>
9
  </div>
@@ -76,95 +75,6 @@
76
 
77
  </div>
78
 
79
- <div id="block_list" class="tabcontent">
80
-
81
- <div class="mo_wpns_divided_layout">
82
- <div class="mo_wpns_setting_layout">
83
- <h2>Manual IP Blocking</h2>
84
-
85
- <h4 class="mo_wpns_setting_layout_inside">Manually block an IP address here:&emsp;&emsp;
86
- <input type="text" name="ManuallyBlockIP" id="ManuallyBlockIP" required placeholder='IP address'pattern="((^|\.)((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]?\d))){4}" style="width: 35%; height: 41px" />&emsp;&emsp;
87
- <input type="button" name="BlockIP" id="BlockIP" value="Manual Block IP" class="mo_wpsn_button mo_wpsn_button1" />
88
- </h4>
89
-
90
- <h3 class="mo_wpns_setting_layout_inside"><b>Blocked IP's</b>
91
- </h3>
92
- <h4 class="mo_wpns_setting_layout_inside">&emsp;&emsp;&emsp;
93
-
94
- <div id="blockIPtable">
95
- <table id="blockedips_table" class="display">
96
- <thead><tr><th>IP Address&emsp;&emsp;</th><th>Reason&emsp;&emsp;</th><th>Blocked Until&emsp;&emsp;</th><th>Blocked Date&emsp;&emsp;</th><th>Action&emsp;&emsp;</th></tr></thead>
97
- <tbody>
98
-
99
- <?php
100
- $mo_wpns_handler = new MoWpnsHandler();
101
- $blockedips = $mo_wpns_handler->get_blocked_ips();
102
- $whitelisted_ips = $mo_wpns_handler->get_whitelisted_ips();
103
- $disabled = '';
104
- global $dirName;
105
- foreach($blockedips as $blockedip)
106
- {
107
- echo "<tr class='mo_wpns_not_bold'><td>".$blockedip->ip_address."</td><td>".$blockedip->reason."</td><td>";
108
- if(empty($blockedip->blocked_for_time))
109
- echo "<span class=redtext>Permanently</span>";
110
- else
111
- echo date("M j, Y, g:i:s a",$blockedip->blocked_for_time);
112
- echo "</td><td>".date("M j, Y, g:i:s a",$blockedip->created_timestamp)."</td><td><a ".$disabled." onclick=unblockip('".$blockedip->id."')>Unblock IP</a></td></tr>";
113
- }
114
- ?>
115
- </tbody>
116
- </table>
117
- </div>
118
- </h4>
119
- </div>
120
- <div class="mo_wpns_setting_layout">
121
- <h2>IP Whitelisting</h2>
122
- <h4 class="mo_wpns_setting_layout_inside">Add new IP address to whitelist:&emsp;&emsp;
123
- <input type="text" name="IPWhitelist" id="IPWhitelist" required placeholder='IP address'pattern="((^|\.)((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]?\d))){4}" style="width: 40%; height: 41px"/>&emsp;&emsp;
124
- <input type="button" name="WhiteListIP" id="WhiteListIP" value="Whitelist IP" class="mo_wpsn_button mo_wpsn_button1" />
125
-
126
- </h4>
127
- <h3 class="mo_wpns_setting_layout_inside">Whitelist IP's
128
- </h3>
129
- <h4 class="mo_wpns_setting_layout_inside">&emsp;&emsp;&emsp;
130
-
131
- <div id="WhiteListIPtable">
132
- <table id="whitelistedips_table" class="display">
133
- <thead><tr><th>IP Address</th><th>Whitelisted Date</th><th>Remove from Whitelist</th></tr></thead>
134
- <tbody>
135
- <?php
136
- foreach($whitelisted_ips as $whitelisted_ip)
137
- {
138
- echo "<tr class='mo_wpns_not_bold'><td>".$whitelisted_ip->ip_address."</td><td>".date("M j, Y, g:i:s a",$whitelisted_ip->created_timestamp)."</td><td><a ".$disabled." onclick=removefromwhitelist('".$whitelisted_ip->id."')>Remove</a></td></tr>";
139
- }
140
-
141
- echo' </tbody>
142
- </table>';
143
- ?>
144
- </div>
145
- </h4>
146
- </div>
147
-
148
-
149
-
150
- <div class="mo_wpns_setting_layout">
151
- <h2>IP LookUp</h2>
152
- <h4 class="mo_wpns_setting_layout_inside">Enter IP address you Want to check:&emsp;&emsp;
153
- <input type="text" name="ipAddresslookup" id="ipAddresslookup" required placeholder='IP address'pattern="((^|\.)((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]?\d))){4}" style="width: 40%; height: 41px"/>&emsp;&emsp;
154
- <input type="button" name="LookupIP" id="LookupIP" value="LookUp IP" class="mo_wpsn_button mo_wpsn_button1" />
155
- </h4>
156
- <div class="ip_lookup_desc" hidden ></div>
157
-
158
- <div id="resultsIPLookup">
159
- </div>
160
- </div>
161
- </div>
162
-
163
-
164
-
165
-
166
-
167
- </div>
168
 
169
  <div id="real_time" class="tabcontent">
170
  <div class="mo_wpns_divided_layout">
@@ -172,7 +82,7 @@ echo' </tbody>
172
 
173
  <table style="width:100%">
174
  <tr><th align="left">
175
- <h3>Real time IP blocking <strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>:
176
  <br>
177
  <p><i class="mo_wpns_not_bold">Blocking those malicious IPs Which has been detected by miniOrange WAF. This feature contains a list of malicious IPs which is mantained in real time. By enabling this option if any attack has been detected on miniOrange WAF on others wbsite then that IP will be blocked from your site also.</i></p>
178
  </th><th align="right">
@@ -198,7 +108,7 @@ echo' </tbody>
198
  <table style="width:100%">
199
  <tr>
200
  <th align="left">
201
- <h3>Rate Limiting:
202
  <br>
203
  <p><i class="mo_wpns_not_bold">This will protect your Website from Dos attack and block request after a limit exceed.</i></p>
204
  </th>
@@ -207,9 +117,9 @@ echo' </tbody>
207
  <input type=checkbox id='rateL' name='rateL' />
208
  <span class='mo_wpns_slider mo_wpns_round'></span>
209
  </label>
210
- </th>
211
-
212
- </h3>
213
  </tr>
214
  </table>
215
  </div>
@@ -245,7 +155,7 @@ echo' </tbody>
245
  <div class="mo_wpns_setting_layout">
246
  <table style="width:100%">
247
  <tr><th align="left">
248
- <h3>Rate Limiting for Crawlers<strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>:
249
  <br>
250
  <p><i class="mo_wpns_not_bold">Web crawlers crawl your Webstie for increasing ranking in the search engine. But sometimes they can make so many request to the server that the service can get damage.By enabling this feature you can provide limit at which a crawler can visit your site.</i></p>
251
  </th><th align="right">
@@ -261,7 +171,7 @@ echo' </tbody>
261
  <div class="mo_wpns_setting_layout">
262
  <table style="width:100%">
263
  <tr><th align="left">
264
- <h3>Fake Web Crawler Protection<strong style="color: red"><a href="admin.php?page=mo-2fa_upgrade"> [Premium Feature] </a></strong>:
265
  <br>
266
  <p><i class="mo_wpns_not_bold">Web Crawlers are used for scaning the Website and indexing it. Google, Bing, etc. are the top crwalers which increase your site's indexing in the seach engine. There are several fake crawlers which can damage your site. By enabling this feature all fake google and bing crawlers will be blocked. </i></p>
267
  </th><th align="right">
@@ -277,7 +187,7 @@ echo' </tbody>
277
  <div class="mo_wpns_setting_layout">
278
  <table style="width:100%">
279
  <tr><th align="left">
280
- <h3>BotNet Protection<strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>:
281
  <br>
282
  <p><i class="mo_wpns_not_bold"> BotNet is a network of robots or army of robots. The BotNet is used for Distributed denial of service attack. The attacker sends too many requests from multiple IPs to a service so that the legitimate traffic can not get the service. By enabling this your Website will be protected from such kind of attacks. </i>
283
  </p>
@@ -320,7 +230,7 @@ echo' </tbody>
320
  <div class="mo_wpns_setting_layout">
321
  <table style="width:100%">
322
  <tr><th align="left">
323
- <h3>Website firewall on plugin level:
324
  <br>
325
  <p><i class="mo_wpns_not_bold">This will activate WAF after the WordPress load. This will block illegitimate requests after making connection to WordPress. This will check Every Request in plugin itself.</i></p>
326
  </th><th align="right">
@@ -331,7 +241,7 @@ echo' </tbody>
331
  </tr></th>
332
  </h3>
333
  <tr><th align="left">
334
- <h3>Website firewall on .htaccess level <strong style="color: #20b2aa">[Recommended] </strong>:
335
  <br>
336
  <p><i class="mo_wpns_not_bold">This will activate WAF before the WordPress load. This will block illegitimate request before any connection to WordPress. This level doesnot allow illegal requests to before any page gets loaded.</i></p>
337
  </th><th align="right">
@@ -371,7 +281,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
371
 
372
  <th align="left"><h2> SQL Injection Protection <strong style="color: #20b2aa">[Basic Level Protection] </strong>::
373
 
374
- <p><i class="mo_wpns_not_bold">SQL Injection attacks are used for attack on database. This option will block all illegal requests which tries to access your database. <a href="admin.php?page=mo_2fa_upgrade"><strong style="color: #20b2aa">Advance Signatures</strong></a></i></p>
375
  </th>
376
  <th align="right">
377
  <label class='mo_wpns_switch'>
@@ -386,7 +296,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
386
  <tr>
387
  <th align="left"><h2> Cross Site scripting Protection <strong style="color: #20b2aa">[Basic Level Protection] </strong>::
388
  <br>
389
- <p><i class="mo_wpns_not_bold">cross site scripting is used for script attacks. This will block illegal scripting on website. <a href="admin.php?page=mo_2fa_upgrade"><strong style="color: #20b2aa">Advance Signatures</strong></a></i></p>
390
  </th>
391
  <th align="right">
392
  <label class='mo_wpns_switch'>
@@ -398,7 +308,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
398
  <tr>
399
  <th align="left"><h2> Local File Inclusion Protection <strong style="color: #20b2aa">[Basic Level Protection] </strong>::
400
  <br>
401
- <p><i class="mo_wpns_not_bold">Local File inclusion is used for making changes to the local files of the server. This option will block Local File Inclusion. <a href="admin.php?page=mo_2fa_upgrade"><strong style="color: #20b2aa">Advance Signatures</strong></a></i></p>
402
  </th>
403
  <th align="right">
404
  <label class='mo_wpns_switch'>
@@ -409,7 +319,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
409
  </h2></tr>
410
 
411
  <tr>
412
- <th align="left"><h2> Remote File Inclusion Protection <strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>::
413
  <br>
414
  <p><i class="mo_wpns_not_bold">Remote File Inclusion is used by attackers for adding malicious files from remote server to your server.This option will block Remote File Inclusion Attacks.</i></p>
415
  </th>
@@ -422,7 +332,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
422
  </h2></tr>
423
 
424
  <tr>
425
- <th align="left"><h2> Remote Code Execution Protection <strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>::
426
  <br>
427
  <p><i class="mo_wpns_not_bold">Remote Code Execution is used for executing malicious commands or files in your server.This option will block Remote File Inclusion </i></p>
428
  </th>
@@ -435,7 +345,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
435
  </h2>
436
  </tr>
437
  <tr>
438
- <th align="left"><h2> SQL Injection Protection <strong style="color: #20b2aa">[Advance Level Protection]</strong> <strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>::
439
  <br>
440
  <p><i class="mo_wpns_not_bold">Advance Level Protection includes advance signatures to detect SQL injection. It is the recommended protection for all websites. </i></p>
441
  </th>
@@ -448,7 +358,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
448
  </h2>
449
  </tr>
450
  <tr>
451
- <th align="left"><h2> Cross Site scripting Protection<strong style="color: #20b2aa"> [Advance Level Protection]</strong> <strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>::
452
  <br>
453
  <p><i class="mo_wpns_not_bold">Advance Level Protection includes advance signatures to detect Cross Site Scripting attacks.</i></p>
454
  </th>
@@ -461,7 +371,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
461
  </h2>
462
  </tr>
463
  <tr>
464
- <th align="left"><h2> Local File Inclusion Protection Protection<strong style="color: #20b2aa"> [Advance Level Protection]</strong> <strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>::
465
  <br>
466
  <p><i class="mo_wpns_not_bold">Advance Level Protection includes advance signatures to detect LFI attacks on your website. Advance protection covers all files of your server to get protected from any kind of LFI attack.</i></p>
467
  </th>
@@ -503,8 +413,6 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
503
  document.getElementById('htaccessChange').style.display="none";
504
  document.getElementById('rateLFD').style.display="none";
505
  jQuery('#resultsIPLookup').empty();
506
-
507
-
508
  var Rate_request = "<?php echo get_option('Rate_request');?>";
509
  var Rate_limiting = "<?php echo get_option('Rate_limiting');?>";
510
  var actionValue = "<?php echo get_option('actionRateL');?>";
@@ -529,6 +437,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
529
  }
530
  }
531
  jQuery('#rateL').click(function(){
 
532
  var rateL = jQuery("input[name='rateL']:checked").val();
533
 
534
  document.getElementById('rateLFD').style.display="none";
@@ -564,36 +473,38 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
564
  if(response == 'RateEnabled')
565
  {
566
  jQuery('#wpns_message').empty();
567
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Rate Limiting is Enabled.</div>");
568
  document.getElementById('rateLFD').style.display="block";
569
- window.scrollTo({ top: 0, behavior: 'smooth' });
 
570
  }
571
  else if(response == 'Ratedisabled')
572
  {
573
  jQuery('#wpns_message').empty();
574
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Rate Limiting is disabled.</div>");
575
- window.scrollTo({ top: 0, behavior: 'smooth' });
576
  }
577
  else if(response == 'WAFNotEnabled')
578
  {
579
  jQuery('#wpns_message').empty();
580
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Enable WAF to use Rate Limiting.</div>");
581
- window.scrollTo({ top: 0, behavior: 'smooth' });
582
-
 
 
583
  document.getElementById('rateLFD').style.display="none";
584
  }
585
  else if(response == 'NonceDidNotMatch')
586
  {
587
  jQuery('#wpns_message').empty();
588
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Nonce verification failed.</div>");
589
- window.scrollTo({ top: 0, behavior: 'smooth' });
590
  document.getElementById('rateLFD').style.display="none";
591
  }
592
  else
593
  {
594
  jQuery('#wpns_message').empty();
595
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' ><b>ERROR</b> : An unknown error has occured</div>");
596
- window.scrollTo({ top: 0, behavior: 'smooth' });
597
  }
598
 
599
  });
@@ -607,6 +518,7 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
607
  var nonce = '<?php echo wp_create_nonce("IPLookUPNonce");?>';
608
  jQuery("#resultsIPLookup").empty();
609
  jQuery("#resultsIPLookup").append("<img src='<?php echo $img_loader_url;?>'>");
 
610
  jQuery("#resultsIPLookup").slideDown(400);
611
  var data = {
612
  'action' : 'wpns_login_security',
@@ -619,22 +531,22 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
619
  {
620
  jQuery("#resultsIPLookup").empty();
621
  jQuery('#wpns_message').empty();
622
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP did not match required format.</div>");
623
- window.scrollTo({ top: 0, behavior: 'smooth' });
624
  }
625
  else if(response == 'INVALID_IP')
626
  {
627
  jQuery("#resultsIPLookup").empty();
628
  jQuery('#wpns_message').empty();
629
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP entered is invalid.</div>");
630
- window.scrollTo({ top: 0, behavior: 'smooth' });
631
  }
632
  else if(response.geoplugin_status == 404)
633
  {
634
  jQuery("#resultsIPLookup").empty();
635
  jQuery('#wpns_message').empty();
636
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP details not found.</div>");
637
- window.scrollTo({ top: 0, behavior: 'smooth' });
638
  }
639
  else if (response.geoplugin_status == 200 ||response.geoplugin_status == 206) {
640
  jQuery('#resultsIPLookup').empty();
@@ -666,20 +578,23 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
666
  if(response == 'RateEnabled')
667
  {
668
  jQuery('#wpns_message').empty();
669
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Rate Limiting is Saved.</div>");
670
- window.scrollTo({ top: 0, behavior: 'smooth' });
 
671
  }
672
  else if(response == 'Ratedisabled')
673
  {
674
  jQuery('#wpns_message').empty();
675
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >Rate Limiting is disabled.</div>");
676
- window.scrollTo({ top: 0, behavior: 'smooth' });
 
677
  }
678
  else
679
  {
680
  jQuery('#wpns_message').empty();
681
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' ><b>ERROR</b> : An unknown error has occured.</div>");
682
- window.scrollTo({ top: 0, behavior: 'smooth' });
 
683
  }
684
 
685
  });
@@ -753,14 +668,14 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
753
  if(response == 'SQLenable')
754
  {
755
  jQuery('#wpns_message').empty();
756
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >SQL Injection protection is enabled</div>");
757
- window.scrollTo({ top: 0, behavior: 'smooth' });
758
  }
759
  else
760
  {
761
  jQuery('#wpns_message').empty();
762
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >SQL Injection protection is disabled.</div>");
763
- window.scrollTo({ top: 0, behavior: 'smooth' });
764
  }
765
 
766
  });
@@ -788,15 +703,14 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
788
  if(response == 'limitSaved')
789
  {
790
  jQuery('#wpns_message').empty();
791
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Limit of attacks has been saved.</div>");
792
- window.scrollTo({ top: 0, behavior: 'smooth' });
793
  }
794
  else
795
  {
796
  jQuery('#wpns_message').empty();
797
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >An Error occured while saving the settings.</div>");
798
- window.scrollTo({ top: 0, behavior: 'smooth' });
799
- }
800
 
801
  });
802
 
@@ -824,14 +738,14 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
824
  if(response == 'XSSenable')
825
  {
826
  jQuery('#wpns_message').empty();
827
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >XSS detection is enabled</div>");
828
- window.scrollTo({ top: 0, behavior: 'smooth' });
829
  }
830
  else
831
  {
832
  jQuery('#wpns_message').empty();
833
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >XSS detection is disabled.</div>");
834
- window.scrollTo({ top: 0, behavior: 'smooth' });
835
  }
836
 
837
  });
@@ -857,14 +771,14 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
857
  if(response == 'LFIenable')
858
  {
859
  jQuery('#wpns_message').empty();
860
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >LFI detection is enabled</div>");
861
- window.scrollTo({ top: 0, behavior: 'smooth' });
862
  }
863
  else
864
  {
865
  jQuery('#wpns_message').empty();
866
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >LFI detection is disabled.</div>");
867
- window.scrollTo({ top: 0, behavior: 'smooth' });
868
  }
869
 
870
  });
@@ -929,16 +843,14 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
929
  jQuery('#limitAttack').val(limitAttack);
930
  }
931
  jQuery('#wpns_message').empty();
932
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >WAF is enabled on Plugin level</div>");
933
- window.scrollTo({ top: 0, behavior: 'smooth' });
934
-
935
-
936
  }
937
  else
938
  {
939
  jQuery('#wpns_message').empty();
940
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >WAF is disabled on plugin level.</div>");
941
- window.scrollTo({ top: 0, behavior: 'smooth' });
942
  document.getElementById('AttackTypes').style.display="none";
943
  }
944
 
@@ -1006,14 +918,14 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
1006
  if(response == 'HWAFdisabled')
1007
  {
1008
  jQuery('#wpns_message').empty();
1009
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >WAF is disabled</div>");
1010
- window.scrollTo({ top: 0, behavior: 'smooth' });
1011
  }
1012
  else
1013
  {
1014
  jQuery('#wpns_message').empty();
1015
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >An error has occured while deactivating WAF.</div>");
1016
- window.scrollTo({ top: 0, behavior: 'smooth' });
1017
  }
1018
  document.getElementById('AttackTypes').style.display="none";
1019
 
@@ -1035,20 +947,15 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
1035
  if(response == 'HWAFEnabled')
1036
  {
1037
  jQuery('#wpns_message').empty();
1038
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >WAF is enabled on htaccess level</div>");
1039
- window.scrollTo({ top: 0, behavior: 'smooth' });
1040
  }
1041
  else if(response =='HWAFEnabledFailed')
1042
  {
1043
  jQuery('#wpns_message').empty();
1044
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >An error has occured while activating WAF.</div>");
1045
- window.scrollTo({ top: 0, behavior: 'smooth' });
1046
- }
1047
- else
1048
- {
1049
- window.scrollTo({ top: 0, behavior: 'smooth' });
1050
  }
1051
-
1052
  });
1053
 
1054
 
@@ -1067,8 +974,8 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
1067
  document.getElementById("htaccessWAF").disabled = false;
1068
 
1069
  jQuery('#wpns_message').empty();
1070
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >WAF activation canceled</div>");
1071
- window.scrollTo({ top: 0, behavior: 'smooth' });
1072
 
1073
  });
1074
  jQuery('#CDhtaccess').click(function(){
@@ -1123,35 +1030,34 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
1123
  jQuery('#limitAttack').val(limitAttack);
1124
  }
1125
  jQuery('#wpns_message').empty();
1126
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >WAF is enabled on htaccess Level</div>");
1127
- window.scrollTo({ top: 0, behavior: 'smooth' });
1128
- }
1129
  }
1130
  else if(response == 'HWAFEnabledFailed')
1131
  {
1132
  jQuery('#wpns_message').empty();
1133
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >An error occured while activating WAF</div>");
1134
- window.scrollTo({ top: 0, behavior: 'smooth' });
1135
 
1136
  }
1137
  else if(response == 'HWAFdisabledFailed')
1138
  {
1139
  jQuery('#wpns_message').empty();
1140
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >An error occured while deactivating WAF</div>");
1141
- window.scrollTo({ top: 0, behavior: 'smooth' });
1142
  }
1143
  else if(response == 'HWAFdisabled')
1144
  {
1145
  jQuery('#wpns_message').empty();
1146
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >WAF is disabled on htaccess Level.</div>");
1147
- window.scrollTo({ top: 0, behavior: 'smooth' });
1148
  document.getElementById('AttackTypes').style.display="none";
1149
  }
1150
  else
1151
  {
1152
  jQuery('#wpns_message').empty();
1153
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >An error has occured.There might be another WAF exists.</div>");
1154
- window.scrollTo({ top: 0, behavior: 'smooth' });
1155
  }
1156
 
1157
  });
@@ -1170,20 +1076,14 @@ echo "<a href='". $url."' download='".$nameDownload."'>";?>
1170
 
1171
  jQuery('#RLPage').click(function(){
1172
  document.getElementById("RateLimitTab").click();
1173
- window.scrollTo({ top: 0, behavior: 'smooth' });
1174
  });
1175
 
1176
  jQuery('#SettingPage').click(function(){
1177
  document.getElementById("settingsTab").click();
1178
- window.scrollTo({ top: 0, behavior: 'smooth' });
1179
- });
1180
- jQuery('#IPBlockingWhitelistPage').click(function(){
1181
- document.getElementById("BlockWhiteTab").click();
1182
- window.scrollTo({ top: 0, behavior: 'smooth' });
1183
  });
 
1184
  jQuery('#RTBPage').click(function(){
1185
  document.getElementById("RealTimeTab").click();
1186
- window.scrollTo({ top: 0, behavior: 'smooth' });
1187
  });
1188
 
1189
  function waf_function(evt, cityName) {
@@ -1196,10 +1096,15 @@ function waf_function(evt, cityName) {
1196
  for (i = 0; i < tablinks.length; i++) {
1197
  tablinks[i].className = tablinks[i].className.replace(" active", "");
1198
  }
1199
- document.getElementById(cityName).style.display = "block";
1200
 
1201
  localStorage.setItem("lastTab",cityName);
1202
  evt.currentTarget.className += " active";
 
 
 
 
 
 
1203
  }
1204
 
1205
 
@@ -1213,11 +1118,7 @@ function waf_function(evt, cityName) {
1213
  document.getElementById("settingsTab").click();
1214
  }
1215
 
1216
- else if(tab == "block_list")
1217
- {
1218
- document.getElementById("BlockWhiteTab").click();
1219
- }
1220
-
1221
  else if(tab == "real_time")
1222
  {
1223
  document.getElementById("RealTimeTab").click();
@@ -1252,35 +1153,35 @@ jQuery('#BlockIP').click(function(){
1252
  if(response == 'empty IP')
1253
  {
1254
  jQuery('#wpns_message').empty();
1255
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP can not be blank.</div>");
1256
- window.scrollTo({ top: 0, behavior: 'smooth' });
1257
  }
1258
  else if(response == 'already blocked')
1259
  {
1260
  jQuery('#wpns_message').empty();
1261
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP is already blocked.</div>");
1262
- window.scrollTo({ top: 0, behavior: 'smooth' });
1263
  }
1264
  else if(response == "INVALID_IP_FORMAT")
1265
  {
1266
  jQuery('#wpns_message').empty();
1267
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP does not match required format.</div>");
1268
- window.scrollTo({ top: 0, behavior: 'smooth' });
1269
 
1270
  }
1271
  else if(response == "IP_IN_WHITELISTED")
1272
  {
1273
  jQuery('#wpns_message').empty();
1274
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP is whitelisted can not be blocked.</div>");
1275
- window.scrollTo({ top: 0, behavior: 'smooth' });
1276
 
1277
  }
1278
  else
1279
  {
1280
  jQuery('#wpns_message').empty();
1281
  refreshblocktable(response);
1282
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >IP Blocked Sucessfully.</div>");
1283
- window.scrollTo({ top: 0, behavior: 'smooth' });
1284
  }
1285
 
1286
  });
@@ -1308,30 +1209,30 @@ jQuery('#WhiteListIP').click(function(){
1308
  if(response == 'EMPTY IP')
1309
  {
1310
  jQuery('#wpns_message').empty();
1311
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP can not be empty.</div>");
1312
- window.scrollTo({ top: 0, behavior: 'smooth' });
1313
 
1314
  }
1315
  else if(response == 'INVALID_IP')
1316
  {
1317
  jQuery('#wpns_message').empty();
1318
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP does not match required format.</div>");
1319
- window.scrollTo({ top: 0, behavior: 'smooth' });
1320
 
1321
  }
1322
  else if(response == 'IP_ALREADY_WHITELISTED')
1323
  {
1324
  jQuery('#wpns_message').empty();
1325
- jQuery('#wpns_message').append("<div class= 'notice notice-error is-dismissible' style='height : 25px;padding-top: 10px; ' >IP is already whitelisted.</div>");
1326
- window.scrollTo({ top: 0, behavior: 'smooth' });
1327
 
1328
  }
1329
  else
1330
  {
1331
  jQuery('#wpns_message').empty();
1332
  refreshWhiteListTable(response);
1333
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >IP whitelisted Sucessfully.</div>");
1334
- window.scrollTo({ top: 0, behavior: 'smooth' });
1335
 
1336
  }
1337
  });
@@ -1362,15 +1263,15 @@ function unblockip(id) {
1362
  if(response=="UNKNOWN_ERROR")
1363
  {
1364
  jQuery('#wpns_message').empty();
1365
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Unknow Error occured while unblocking IP.</div>");
1366
- window.scrollTo({ top: 0, behavior: 'smooth' });
1367
  }
1368
  else
1369
  {
1370
  jQuery('#wpns_message').empty();
1371
  refreshblocktable(response);
1372
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >IP UnBlocked Sucessfully.</div>");
1373
- window.scrollTo({ top: 0, behavior: 'smooth' });
1374
  }
1375
  });
1376
 
@@ -1393,15 +1294,15 @@ function removefromwhitelist(id)
1393
  if(response == 'UNKNOWN_ERROR')
1394
  {
1395
  jQuery('#wpns_message').empty();
1396
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >Unknow Error occured while removing IP from Whitelist.</div>");
1397
- window.scrollTo({ top: 0, behavior: 'smooth' });
1398
  }
1399
  else
1400
  {
1401
  jQuery('#wpns_message').empty();
1402
  refreshWhiteListTable(response);
1403
- jQuery('#wpns_message').append("<div class= 'notice notice-success is-dismissible' style='height : 25px;padding-top: 10px; ' >IP removed from Whitelist.</div>");
1404
- window.scrollTo({ top: 0, behavior: 'smooth' });
1405
  }
1406
  });
1407
 
@@ -1418,6 +1319,11 @@ function refreshWhiteListTable(html)
1418
 
1419
  jQuery('#WhiteListIPtable').html(html);
1420
  }
 
 
 
 
 
1421
  </script>
1422
 
1423
 
3
  <div class="mo_wpns_tab">
4
  <button class="tablinks" onclick="waf_function(event, 'waf_dash')" id="defaultOpen">Firewall Dashboard</button>
5
  <button class="tablinks" onclick="waf_function(event, 'settings')" id="settingsTab">Settings</button>
 
6
  <button class="tablinks" onclick="waf_function(event, 'real_time')" id="RealTimeTab">Real Time Blocking</button>
7
  <button class="tablinks" onclick="waf_function(event, 'rate_limiting')" id="RateLimitTab">Rate Limiting</button>
8
  </div>
75
 
76
  </div>
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  <div id="real_time" class="tabcontent">
80
  <div class="mo_wpns_divided_layout">
82
 
83
  <table style="width:100%">
84
  <tr><th align="left">
85
+ <h3>Real Time IP Blocking <strong style="color: red"><a href="admin.php?page=mo_2fa_upgrade"> [Premium Feature] </a></strong>:
86
  <br>
87
  <p><i class="mo_wpns_not_bold">Blocking those malicious IPs Which has been detected by miniOrange WAF. This feature contains a list of malicious IPs which is mantained in real time. By enabling this option if any attack has been detected on miniOrange WAF on others wbsite then that IP will be blocked from your site also.</i></p>
88
  </th><th align="right">
108
  <table style="width:100%">
109
  <tr>
110
  <th align="left">
111
+ <h3>Rate Limiting:</h3>
112
  <br>
113
  <p><i class="mo_wpns_not_bold">This will protect your Website from Dos attack and block request after a limit exceed.</i></p>
114
  </th>
117
  <input type=checkbox id='rateL' name='rateL' />
118
  <span class='mo_wpns_slider mo_wpns_round'></span>
119
  </label>
120
+ <br>
121
+ <strong><div id="enableWAFLink" onclick="waf_function(event, 'settings')" class="link"></div></strong>
122
+ </th>
123
  </tr>
124
  </table>
125
  </div>
155
  <div class="mo_wpns_setting_layout">
156
  <table style="width:100%">
157
  <tr><th align="left">
158
+ <h3>Rate Limiting for Crawlers<strong style="color: red"><a href="admin.php?page=upgrade"> [Premium Feature] </a></strong>:
159
  <br>
160
  <p><i class="mo_wpns_not_bold">Web crawlers crawl your Webstie for increasing ranking in the search engine. But sometimes they can make so many request to the server that the service can get damage.By enabling this feature you can provide limit at which a crawler can visit your site.</i></p>
161
  </th><th align="right">
171
  <div class="mo_wpns_setting_layout">
172
  <table style="width:100%">
173
  <tr><th align="left">
174
+ <h3>Fake Web Crawler Protection<strong style="color: red"><a href="admin.php?page=upgrade"> [Premium Feature] </a></strong>:
175
  <br>
176
  <p><i class="mo_wpns_not_bold">Web Crawlers are used for scaning the Website and indexing it. Google, Bing, etc. are the top crwalers which increase your site's indexing in the seach engine. There are several fake crawlers which can damage your site. By enabling this feature all fake google and bing crawlers will be blocked. </i></p>
177
  </th><th align="right">
187
  <div class="mo_wpns_setting_layout">
188
  <table style="width:100%">
189
  <tr><th align="left">
190
+ <h3>BotNet Protection<strong style="color: red"><a href="admin.php?page=upgrade"> [Premium Feature] </a></strong>:
191
  <br>
192
  <p><i class="mo_wpns_not_bold"> BotNet is a network of robots or army of robots. The BotNet is used for Distributed denial of service attack. The attacker sends too many requests from multiple IPs to a service so that the legitimate traffic can not get the service. By enabling this your Website will be protected from such kind of attacks. </i>
193
  </p>
230
  <div class="mo_wpns_setting_layout">
231
  <table style="width:100%">
232
  <tr><th align="left">
233
+ <h3>Website Firewall on Plugin Level:
234
  <br>
235
  <p><i class="mo_wpns_not_bold">This will activate WAF after the WordPress load. This will block illegitimate requests after making connection to WordPress. This will check Every Request in plugin itself.</i></p>
236
  </th><th align="right">
241
  </tr></th>
242
  </h3>
243
  <tr><th align="left">
244
+ <h3>Website Firewall on .htaccess Level <strong style="color: #20b2aa">[Recommended] </strong>:
245
  <br>
246
  <p><i class="mo_wpns_not_bold">This will activate WAF before the WordPress load. This will block illegitimate request before any connection to WordPress. This level doesnot allow illegal requests to before any page gets loaded.</i></p>
247
  </th><th align="right">
281
 
282
  <th align="left"><h2> SQL Injection Protection <strong style="color: #20b2aa">[Basic Level Protection] </strong>::
283
 
284
+ <p><i class="mo_wpns_not_bold">SQL Injection attacks are used for attack on database. This option will block all illegal requests which tries to access your database. <a href="admin.php?page=upgrade"><strong style="color: #20b2aa">Advance Signatures</strong></a></i></p>
285
  </th>
286
  <th align="right">
287
  <label class='mo_wpns_switch'>
296
  <tr>
297
  <th align="left"><h2> Cross Site scripting Protection <strong style="color: #20b2aa">[Basic Level Protection] </strong>::
298
  <br>
299
+ <p><i class="mo_wpns_not_bold">cross site scripting is used for script attacks. This will block illegal scripting on website. <a href="admin.php?page=upgrade"><strong style="color: #20b2aa">Advance Signatures</strong></a></i></p>
300
  </th>
301
  <th align="right">
302
  <label class='mo_wpns_switch'>
308
  <tr>
309
  <th align="left"><h2> Local File Inclusion Protection <strong style="color: #20b2aa">[Basic Level Protection] </strong>::
310
  <br>
311
+ <p><i class="mo_wpns_not_bold">Local File inclusion is used for making changes to the local files of the server. This option will block Local File Inclusion. <a href="admin.php?page=upgrade"><strong style="color: #20b2aa">Advance Signatures</strong></a></i></p>
312
  </th>
313
  <th align="right">
314
  <label class='mo_wpns_switch'>
319
  </h2></tr>
320
 
321
  <tr>
322
+ <th align="left"><h2> Remote File Inclusion Protection <strong style="color: red"><a href="admin.php?page=upgrade"> [Premium Feature] </a></strong>::
323
  <br>
324
  <p><i class="mo_wpns_not_bold">Remote File Inclusion is used by attackers for adding malicious files from remote server to your server.This option will block Remote File Inclusion Attacks.</i></p>
325
  </th>
332
  </h2></tr>
333
 
334
  <tr>
335
+ <th align="left"><h2> Remote Code Execution Protection <strong style="color: red"><a href="admin.php?page=upgrade"> [Premium Feature] </a></strong>::
336
  <br>
337
  <p><i class="mo_wpns_not_bold">Remote Code Execution is used for executing malicious commands or files in your server.This option will block Remote File Inclusion </i></p>
338
  </th>
345
  </h2>
346
  </tr>
347
  <tr>
348
+ <th align="left"><h2> SQL Injection Protection <strong style="color: #20b2aa">[Advance Level Protection]</strong> <strong style="color: red"><a href="admin.php?page=upgrade"> [Premium Feature] </a></strong>::
349
  <br>
350
  <p><i class="mo_wpns_not_bold">Advance Level Protection includes advance signatures to detect SQL injection. It is the recommended protection for all websites. </i></p>
351
  </th>
358
  </h2>
359
  </tr>
360
  <tr>
361
+ <th align="left"><h2> Cross Site scripting Protection<strong style="color: #20b2aa"> [Advance Level Protection]</strong> <strong style="color: red"><a href="admin.php?page=upgrade"> [Premium Feature] </a></strong>::
362
  <br>
363
  <p><i class="mo_wpns_not_bold">Advance Level Protection includes advance signatures to detect Cross Site Scripting attacks.</i></p>
364
  </th>
371
  </h2>
372
  </tr>
373
  <tr>
374
+ <th align="left"><h2> Local File Inclusion Protection Protection<strong style="color: #20b2aa"> [Advance Level Protection]</strong> <strong style="color: red"><a href="admin.php?page=upgrade"> [Premium Feature] </a></strong>::
375
  <br>
376
  <p><i class="mo_wpns_not_bold">Advance Level Protection includes advance signatures to detect LFI attacks on your website. Advance protection covers all files of your server to get protected from any kind of LFI attack.</i></p>
377
  </th>
413
  document.getElementById('htaccessChange').style.display="none";
414
  document.getElementById('rateLFD').style.display="none";
415
  jQuery('#resultsIPLookup').empty();
 
 
416
  var Rate_request = "<?php echo get_option('Rate_request');?>";
417
  var Rate_limiting = "<?php echo get_option('Rate_limiting');?>";
418
  var actionValue = "<?php echo get_option('actionRateL');?>";
437
  }
438
  }
439
  jQuery('#rateL').click(function(){
440
+ jQuery('#enableWAFLink').empty();
441
  var rateL = jQuery("input[name='rateL']:checked").val();
442
 
443
  document.getElementById('rateLFD').style.display="none";
473
  if(response == 'RateEnabled')
474
  {
475
  jQuery('#wpns_message').empty();
 
476
  document.getElementById('rateLFD').style.display="block";
477
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; Rate Limiting is Enabled.</div></div>");
478
+ window.onload = nav_popup();
479
  }
480
  else if(response == 'Ratedisabled')
481
  {
482
  jQuery('#wpns_message').empty();
483
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; Rate Limiting is disabled.</div></div>");
484
+ window.onload = nav_popup();
485
  }
486
  else if(response == 'WAFNotEnabled')
487
  {
488
  jQuery('#wpns_message').empty();
489
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Enable WAF to use Rate Limiting</div></div>");
490
+ window.onload = nav_popup();
491
+
492
+ jQuery('#enableWAFLink').append("[Click here] To Enable WAF");
493
+ jQuery('#rateL').prop('checked',false);
494
  document.getElementById('rateLFD').style.display="none";
495
  }
496
  else if(response == 'NonceDidNotMatch')
497
  {
498
  jQuery('#wpns_message').empty();
499
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Nonce verification failed.</div></div>");
500
+ window.onload = nav_popup();
501
  document.getElementById('rateLFD').style.display="none";
502
  }
503
  else
504
  {
505
  jQuery('#wpns_message').empty();
506
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; <b>ERROR</b> : An unknown error has occured</div></div>");
507
+ window.onload = nav_popup();
508
  }
509
 
510
  });
518
  var nonce = '<?php echo wp_create_nonce("IPLookUPNonce");?>';
519
  jQuery("#resultsIPLookup").empty();
520
  jQuery("#resultsIPLookup").append("<img src='<?php echo $img_loader_url;?>'>");
521
+
522
  jQuery("#resultsIPLookup").slideDown(400);
523
  var data = {
524
  'action' : 'wpns_login_security',
531
  {
532
  jQuery("#resultsIPLookup").empty();
533
  jQuery('#wpns_message').empty();
534
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP did not match required format.</div></div>");
535
+ window.onload = nav_popup();
536
  }
537
  else if(response == 'INVALID_IP')
538
  {
539
  jQuery("#resultsIPLookup").empty();
540
  jQuery('#wpns_message').empty();
541
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP entered is invalid.</div></div>");
542
+ window.onload = nav_popup();
543
  }
544
  else if(response.geoplugin_status == 404)
545
  {
546
  jQuery("#resultsIPLookup").empty();
547
  jQuery('#wpns_message').empty();
548
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP details not found.</div></div>");
549
+ window.onload = nav_popup();
550
  }
551
  else if (response.geoplugin_status == 200 ||response.geoplugin_status == 206) {
552
  jQuery('#resultsIPLookup').empty();
578
  if(response == 'RateEnabled')
579
  {
580
  jQuery('#wpns_message').empty();
581
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp;Rate Limiting is Saved</div></div>");
582
+ window.onload = nav_popup();
583
+
584
  }
585
  else if(response == 'Ratedisabled')
586
  {
587
  jQuery('#wpns_message').empty();
588
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp;Rate Limiting is disabled.</div></div>");
589
+ window.onload = nav_popup();
590
+
591
  }
592
  else
593
  {
594
  jQuery('#wpns_message').empty();
595
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Limit of attacks should be more than 1.</div></div>");
596
+ window.onload = nav_popup();
597
+
598
  }
599
 
600
  });
668
  if(response == 'SQLenable')
669
  {
670
  jQuery('#wpns_message').empty();
671
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; SQL Injection protection is enabled</div></div>");
672
+ window.onload = nav_popup();
673
  }
674
  else
675
  {
676
  jQuery('#wpns_message').empty();
677
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; SQL Injection protection is disabled.</div></div>");
678
+ window.onload = nav_popup();
679
  }
680
 
681
  });
703
  if(response == 'limitSaved')
704
  {
705
  jQuery('#wpns_message').empty();
706
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; Limit of attacks has been saved.</div></div>");
707
+ window.onload = nav_popup();
708
  }
709
  else
710
  {
711
  jQuery('#wpns_message').empty();
712
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Limit of attacks should be more that 1</div></div>");
713
+ window.onload = nav_popup(); }
 
714
 
715
  });
716
 
738
  if(response == 'XSSenable')
739
  {
740
  jQuery('#wpns_message').empty();
741
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; XSS detection is enabled</div></div>");
742
+ window.onload = nav_popup();
743
  }
744
  else
745
  {
746
  jQuery('#wpns_message').empty();
747
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; XSS detection is disabled.</div></div>");
748
+ window.onload = nav_popup();
749
  }
750
 
751
  });
771
  if(response == 'LFIenable')
772
  {
773
  jQuery('#wpns_message').empty();
774
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; LFI detection is enabled</div></div>");
775
+ window.onload = nav_popup();
776
  }
777
  else
778
  {
779
  jQuery('#wpns_message').empty();
780
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; LFI detection is disabled.</div></div>");
781
+ window.onload = nav_popup();
782
  }
783
 
784
  });
843
  jQuery('#limitAttack').val(limitAttack);
844
  }
845
  jQuery('#wpns_message').empty();
846
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; WAF is enabled on Plugin level</div></div>");
847
+ window.onload = nav_popup();
 
 
848
  }
849
  else
850
  {
851
  jQuery('#wpns_message').empty();
852
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; WAF is disabled on plugin level.</div></div>");
853
+ window.onload = nav_popup();
854
  document.getElementById('AttackTypes').style.display="none";
855
  }
856
 
918
  if(response == 'HWAFdisabled')
919
  {
920
  jQuery('#wpns_message').empty();
921
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; WAF is disabled</div></div>");
922
+ window.onload = nav_popup();
923
  }
924
  else
925
  {
926
  jQuery('#wpns_message').empty();
927
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; An error has occured while deactivating WAF.</div></div>");
928
+ window.onload = nav_popup();
929
  }
930
  document.getElementById('AttackTypes').style.display="none";
931
 
947
  if(response == 'HWAFEnabled')
948
  {
949
  jQuery('#wpns_message').empty();
950
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; WAF is enabled on htaccess level</div></div>");
951
+ window.onload = nav_popup();
952
  }
953
  else if(response =='HWAFEnabledFailed')
954
  {
955
  jQuery('#wpns_message').empty();
956
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; An error has occured while activating WAF.</div></div>");
957
+ window.onload = nav_popup();
 
 
 
 
958
  }
 
959
  });
960
 
961
 
974
  document.getElementById("htaccessWAF").disabled = false;
975
 
976
  jQuery('#wpns_message').empty();
977
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; WAF on htaccess level is disabled </div></div>");
978
+ window.onload = nav_popup();
979
 
980
  });
981
  jQuery('#CDhtaccess').click(function(){
1030
  jQuery('#limitAttack').val(limitAttack);
1031
  }
1032
  jQuery('#wpns_message').empty();
1033
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; WAF is enabled on htaccess Level</div></div>");
1034
+ window.onload = nav_popup(); }
 
1035
  }
1036
  else if(response == 'HWAFEnabledFailed')
1037
  {
1038
  jQuery('#wpns_message').empty();
1039
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp;An error occured while activating WAF</div></div>");
1040
+ window.onload = nav_popup();
1041
 
1042
  }
1043
  else if(response == 'HWAFdisabledFailed')
1044
  {
1045
  jQuery('#wpns_message').empty();
1046
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; An error occured while deactivating WAF</div></div>");
1047
+ window.onload = nav_popup();
1048
  }
1049
  else if(response == 'HWAFdisabled')
1050
  {
1051
  jQuery('#wpns_message').empty();
1052
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; WAF is disabled on htaccess Level.</div></div>");
1053
+ window.onload = nav_popup();
1054
  document.getElementById('AttackTypes').style.display="none";
1055
  }
1056
  else
1057
  {
1058
  jQuery('#wpns_message').empty();
1059
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; An error has occured.There might be another WAF exists.</div></div>");
1060
+ window.onload = nav_popup();
1061
  }
1062
 
1063
  });
1076
 
1077
  jQuery('#RLPage').click(function(){
1078
  document.getElementById("RateLimitTab").click();
 
1079
  });
1080
 
1081
  jQuery('#SettingPage').click(function(){
1082
  document.getElementById("settingsTab").click();
 
 
 
 
 
1083
  });
1084
+
1085
  jQuery('#RTBPage').click(function(){
1086
  document.getElementById("RealTimeTab").click();
 
1087
  });
1088
 
1089
  function waf_function(evt, cityName) {
1096
  for (i = 0; i < tablinks.length; i++) {
1097
  tablinks[i].className = tablinks[i].className.replace(" active", "");
1098
  }
 
1099
 
1100
  localStorage.setItem("lastTab",cityName);
1101
  evt.currentTarget.className += " active";
1102
+ if(cityName == "settings")
1103
+ {
1104
+ jQuery("#settingsTab").addClass(" active");
1105
+ }
1106
+ document.getElementById(cityName).style.display = "block";
1107
+
1108
  }
1109
 
1110
 
1118
  document.getElementById("settingsTab").click();
1119
  }
1120
 
1121
+
 
 
 
 
1122
  else if(tab == "real_time")
1123
  {
1124
  document.getElementById("RealTimeTab").click();
1153
  if(response == 'empty IP')
1154
  {
1155
  jQuery('#wpns_message').empty();
1156
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP can not be blank.</div></div>");
1157
+ window.onload = nav_popup();
1158
  }
1159
  else if(response == 'already blocked')
1160
  {
1161
  jQuery('#wpns_message').empty();
1162
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP is already blocked.</div></div>");
1163
+ window.onload = nav_popup();
1164
  }
1165
  else if(response == "INVALID_IP_FORMAT")
1166
  {
1167
  jQuery('#wpns_message').empty();
1168
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP does not match required format.</div></div>");
1169
+ window.onload = nav_popup();
1170
 
1171
  }
1172
  else if(response == "IP_IN_WHITELISTED")
1173
  {
1174
  jQuery('#wpns_message').empty();
1175
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP is whitelisted can not be blocked.</div></div>");
1176
+ window.onload = nav_popup();
1177
 
1178
  }
1179
  else
1180
  {
1181
  jQuery('#wpns_message').empty();
1182
  refreshblocktable(response);
1183
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP Blocked Sucessfully.</div></div>");
1184
+ window.onload = nav_popup();
1185
  }
1186
 
1187
  });
1209
  if(response == 'EMPTY IP')
1210
  {
1211
  jQuery('#wpns_message').empty();
1212
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP can not be empty.</div></div>");
1213
+ window.onload = nav_popup();
1214
 
1215
  }
1216
  else if(response == 'INVALID_IP')
1217
  {
1218
  jQuery('#wpns_message').empty();
1219
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP does not match required format.</div></div>");
1220
+ window.onload = nav_popup();
1221
 
1222
  }
1223
  else if(response == 'IP_ALREADY_WHITELISTED')
1224
  {
1225
  jQuery('#wpns_message').empty();
1226
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; IP is already whitelisted.</div></div>");
1227
+ window.onload = nav_popup();
1228
 
1229
  }
1230
  else
1231
  {
1232
  jQuery('#wpns_message').empty();
1233
  refreshWhiteListTable(response);
1234
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP whitelisted Sucessfully.</div></div>");
1235
+ window.onload = nav_popup();
1236
 
1237
  }
1238
  });
1263
  if(response=="UNKNOWN_ERROR")
1264
  {
1265
  jQuery('#wpns_message').empty();
1266
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Unknow Error occured while unblocking IP.</div></div>");
1267
+ window.onload = nav_popup();
1268
  }
1269
  else
1270
  {
1271
  jQuery('#wpns_message').empty();
1272
  refreshblocktable(response);
1273
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP UnBlocked Sucessfully.</div></div>");
1274
+ window.onload = nav_popup();
1275
  }
1276
  });
1277
 
1294
  if(response == 'UNKNOWN_ERROR')
1295
  {
1296
  jQuery('#wpns_message').empty();
1297
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_error'><div class='popup_text'>&nbsp; &nbsp; Unknow Error occured while removing IP from Whitelist.</div></div>");
1298
+ window.onload = nav_popup();
1299
  }
1300
  else
1301
  {
1302
  jQuery('#wpns_message').empty();
1303
  refreshWhiteListTable(response);
1304
+ jQuery('#wpns_message').append("<div id='notice_div' class='overlay_success'><div class='popup_text'>&nbsp; &nbsp; IP removed from Whitelist.</div></div>");
1305
+ window.onload = nav_popup();
1306
  }
1307
  });
1308
 
1319
 
1320
  jQuery('#WhiteListIPtable').html(html);
1321
  }
1322
+
1323
+ function nav_popup() {
1324
+ document.getElementById("notice_div").style.width = "40%";
1325
+ setTimeout(function(){ $('#notice_div').fadeOut('slow'); }, 3000);
1326
+ }
1327
  </script>
1328
 
1329