Version Description
- New: Now you can enable 2 factors authentication with Defender and Google Authenticator app, support for iOS and Android
- New: We can define how long the "Remember me" can take affect, via a new Security Tweak, called "Manage Login Duration"
- Improvement: IP Lockout logs now have separate tables, better for performance.
- Fix: Ignore a file in Scanning section sometimes coming back after couple of scans.
- Other minor enhancements/fixes
Download this release
Release Info
Developer | paulkevini |
Plugin | Defender Security – Malware Scanner, Login Security & Firewall |
Version | 1.7 |
Comparing to | |
See all releases |
Code changes from version 1.6.2 to 1.7
- app/behavior/utils.php +27 -75
- app/controller/dashboard.php +122 -2
- app/module/advanced-tools.php +15 -0
- app/module/advanced-tools/component/auth-api.php +307 -0
- app/module/advanced-tools/controller/main.php +463 -0
- app/module/advanced-tools/css/login-admin.css +34 -0
- app/module/advanced-tools/css/login.css +21 -0
- app/module/advanced-tools/img/2factor-disabled.svg +85 -0
- app/module/advanced-tools/img/spinner.svg +49 -0
- app/module/advanced-tools/js/scripts.js +47 -0
- app/module/advanced-tools/model/auth-settings.php +95 -0
- app/module/advanced-tools/view/disabled.php +24 -0
- app/module/advanced-tools/view/layouts/layout.php +30 -0
- app/module/advanced-tools/view/login/disabled.php +97 -0
- app/module/advanced-tools/view/login/enabled.php +52 -0
- app/module/advanced-tools/view/login/otp.php +316 -0
- app/module/advanced-tools/view/main.php +123 -0
- app/module/audit/view/pro-feature.php +1 -1
- app/module/hardener/behavior/widget.php +1 -1
- app/module/hardener/component/disable-file-editor.php +44 -0
- app/module/hardener/component/login-duration-service.php +58 -0
- app/module/hardener/component/login-duration.php +216 -0
- app/module/hardener/component/prevent-php.php +31 -0
- app/module/hardener/component/security-key.php +8 -3
- app/module/hardener/component/servers/apache-service.php +7 -1
- app/module/hardener/controller/main.php +30 -0
- app/module/hardener/js/scripts.js +29 -8
- app/module/hardener/model/settings.php +3 -8
- app/module/hardener/view/rules/change-admin.php +1 -1
- app/module/hardener/view/rules/login-duration.php +53 -0
- app/module/hardener/view/rules/prevent-php-executed.php +49 -18
- app/module/ip-lockout/component/login-protection-api.php +55 -4
- app/module/ip-lockout/controller/main.php +118 -43
- app/module/ip-lockout/js/script.js +33 -1
- app/module/ip-lockout/model/ip-model-legacy.php +167 -0
- app/module/ip-lockout/model/ip-model.php +3 -120
- app/module/ip-lockout/model/log-model-legacy.php +166 -0
- app/module/ip-lockout/model/log-model.php +3 -42
- app/module/ip-lockout/model/settings.php +1 -1
- app/module/ip-lockout/view/layouts/layout.php +3 -3
- app/module/ip-lockout/view/locked.php +62 -61
- app/module/ip-lockout/view/migration.php +35 -0
- app/module/ip-lockout/view/notification/report-free.php +1 -1
- app/module/ip-lockout/view/pro-feature.php +1 -1
- app/module/scan/behavior/core-result.php +20 -6
- app/module/scan/component/scan-api.php +33 -8
- app/module/scan/controller/main.php +0 -1
- app/module/scan/view/automation-free.php +1 -1
- app/module/scan/view/pro-feature.php +1 -1
- app/module/scan/view/setting-free.php +1 -1
- app/view/pro-feature.php +1 -1
- assets/css/defender-icon.css +14 -0
- assets/css/styles.css +10 -0
- assets/img/2factor-disabled.svg +85 -0
- assets/img/android-download.svg +75 -0
- assets/img/ios-download.svg +49 -0
- changelog.txt +11 -1
- languages/wpdef-default.pot +485 -178
- main-activator.php +7 -0
- phpunit.xml +0 -14
- readme.txt +10 -2
- uninstall.php +1 -0
- vendor/binary-to-text-php/Base2n.php +302 -0
- vendor/binary-to-text-php/LICENSE.txt +21 -0
- vendor/binary-to-text-php/README.md +279 -0
- vendor/binary-to-text-php/composer.json +20 -0
- vendor/hammer/base/db-model.php +292 -0
- vendor/hammer/base/view.php +0 -1
- vendor/hammer/vendor/psr/log/.gitignore +0 -1
- vendor/hammer/vendor/wixel/gump/examples/basic_tags.php +0 -24
- vendor/hammer/vendor/wixel/gump/examples/contains.php +0 -48
- vendor/hammer/vendor/wixel/gump/examples/credit_card.php +0 -16
- vendor/hammer/vendor/wixel/gump/examples/custom_validator.php +0 -44
- vendor/hammer/vendor/wixel/gump/examples/escaping_mysql_strings.php +0 -38
- vendor/hammer/vendor/wixel/gump/examples/explicit_fields.php +0 -26
- vendor/hammer/vendor/wixel/gump/examples/files.php +0 -41
- vendor/hammer/vendor/wixel/gump/examples/full_example.php +0 -62
- vendor/hammer/vendor/wixel/gump/examples/guid.php +0 -18
- vendor/hammer/vendor/wixel/gump/examples/handling_errors.php +0 -74
- vendor/hammer/vendor/wixel/gump/examples/match.php +0 -22
- vendor/hammer/vendor/wixel/gump/examples/noise_words.php +0 -18
- vendor/hammer/vendor/wixel/gump/examples/sanitize_string.php +0 -16
- vendor/hammer/vendor/wixel/gump/examples/sanitize_whitelist.php +0 -45
- vendor/hammer/vendor/wixel/gump/examples/street_address.php +0 -22
- vendor/hammer/vendor/wixel/gump/examples/url_exists.php +0 -26
- vendor/hammer/vendor/wixel/gump/examples/utf-8.php +0 -24
- vendor/hammer/vendor/wixel/gump/gump.class.php +2 -0
- vendor/hammer/wp/model.php +37 -9
- vendor/hammer/wp/settings.php +3 -1
- wp-defender.php +1 -2
app/behavior/utils.php
CHANGED
@@ -484,81 +484,6 @@ class Utils extends Behavior {
|
|
484 |
return $defDir;
|
485 |
}
|
486 |
|
487 |
-
/**
|
488 |
-
* @return array|void
|
489 |
-
*/
|
490 |
-
public function submitStatsToDev() {
|
491 |
-
if ( ! $this->getAPIKey() ) {
|
492 |
-
return;
|
493 |
-
}
|
494 |
-
|
495 |
-
$issues = array();
|
496 |
-
$rules = Settings::instance()->getIssues();
|
497 |
-
foreach ( $rules as $rule ) {
|
498 |
-
$issues[] = array(
|
499 |
-
'label' => $rule->getTitle(),
|
500 |
-
'url' => network_admin_url( 'admin.php?page=wdf-hardener' ) . '#' . $rule::$slug
|
501 |
-
);
|
502 |
-
}
|
503 |
-
|
504 |
-
$model = Scan_Api::getLastScan();
|
505 |
-
$count = 0;
|
506 |
-
if ( is_object( $model ) ) {
|
507 |
-
$timestamp = strtotime( $model->dateFinished );
|
508 |
-
|
509 |
-
$res = array(
|
510 |
-
'core_integrity' => $model->getCount( 'core' ),
|
511 |
-
'vulnerability_db' => $model->getCount( 'vuln' ),
|
512 |
-
'file_suspicious' => $model->getCount( 'content' )
|
513 |
-
);
|
514 |
-
|
515 |
-
$count = $model->countAll( Result_Item::STATUS_ISSUE );
|
516 |
-
} else {
|
517 |
-
$timestamp = '';
|
518 |
-
$res = array(
|
519 |
-
'core_integrity' => 0,
|
520 |
-
'vulnerability_db' => 0,
|
521 |
-
'file_suspicious' => 0
|
522 |
-
);
|
523 |
-
}
|
524 |
-
$labels = array(
|
525 |
-
'core_integrity' => esc_html__( "WordPress Core Integrity", wp_defender()->domain ),
|
526 |
-
'vulnerability_db' => esc_html__( "Plugins & Themes vulnerability", wp_defender()->domain ),
|
527 |
-
'file_suspicious' => esc_html__( "Suspicious Code", wp_defender()->domain )
|
528 |
-
);
|
529 |
-
|
530 |
-
$data = array(
|
531 |
-
'domain' => network_home_url(),
|
532 |
-
'timestamp' => $timestamp,
|
533 |
-
'warnings' => $count,
|
534 |
-
'cautions' => count( $issues ),
|
535 |
-
'data_version' => '20160220',
|
536 |
-
'scan_data' => json_encode( array(
|
537 |
-
'scan_result' => $res,
|
538 |
-
'hardener_result' => $issues,
|
539 |
-
'scan_schedule' => array(
|
540 |
-
'is_activated' => \WP_Defender\Module\Scan\Model\Settings::instance()->notification,
|
541 |
-
'time' => \WP_Defender\Module\Scan\Model\Settings::instance()->time,
|
542 |
-
'day' => \WP_Defender\Module\Scan\Model\Settings::instance()->day,
|
543 |
-
'frequency' => \WP_Defender\Module\Scan\Model\Settings::instance()->frequency
|
544 |
-
),
|
545 |
-
'audit_enabled' => false,
|
546 |
-
'audit_page_url' => network_admin_url( 'admin.php?page=wdf-logging' ),
|
547 |
-
'labels' => $labels,
|
548 |
-
'scan_page_url' => network_admin_url( 'admin.php?page=wdf-scan' ),
|
549 |
-
'hardener_page_url' => network_admin_url( 'admin.php?page=wdf-hardener' ),
|
550 |
-
'new_scan_url' => network_admin_url( 'admin.php?page=wdf-scan&wdf-action=new_scan' ),
|
551 |
-
'schedule_scans_url' => network_admin_url( 'admin.php?page=wdf-schedule-scan' ),
|
552 |
-
'settings_page_url' => network_admin_url( 'admin.php?page=wdf-settings' )
|
553 |
-
) ),
|
554 |
-
);
|
555 |
-
|
556 |
-
$end_point = "https://premium.wpmudev.org/api/defender/v1/scan-results";
|
557 |
-
$this->devCall( $end_point, $data, array(
|
558 |
-
'method' => 'POST'
|
559 |
-
) );
|
560 |
-
}
|
561 |
-
|
562 |
/**
|
563 |
* @param null $result
|
564 |
*
|
@@ -616,4 +541,31 @@ class Utils extends Behavior {
|
|
616 |
'iis-7' => 'IIS 7'
|
617 |
) );
|
618 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
619 |
}
|
484 |
return $defDir;
|
485 |
}
|
486 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
487 |
/**
|
488 |
* @param null $result
|
489 |
*
|
541 |
'iis-7' => 'IIS 7'
|
542 |
) );
|
543 |
}
|
544 |
+
|
545 |
+
/**
|
546 |
+
* Get the current page URL
|
547 |
+
*
|
548 |
+
* @return String
|
549 |
+
*/
|
550 |
+
public function currentPageURL() {
|
551 |
+
$protocol = "http";
|
552 |
+
if ( is_ssl() ) {
|
553 |
+
$protocol .= "s";
|
554 |
+
}
|
555 |
+
$url = "$protocol://";
|
556 |
+
if ( $_SERVER["SERVER_PORT"] != "80" ) {
|
557 |
+
$url .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
|
558 |
+
} else {
|
559 |
+
$url .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
|
560 |
+
}
|
561 |
+
|
562 |
+
return apply_filters( 'defender_current_page_url', $url );
|
563 |
+
}
|
564 |
+
|
565 |
+
/**
|
566 |
+
* Blank function
|
567 |
+
*/
|
568 |
+
public function submitStatsToDev() {
|
569 |
+
return;
|
570 |
+
}
|
571 |
}
|
app/controller/dashboard.php
CHANGED
@@ -33,6 +33,7 @@ class Dashboard extends Controller {
|
|
33 |
$this->add_ajax_action( 'toggleBlacklistWidget', 'toggleBlacklistWidget' );
|
34 |
$this->add_ajax_action( 'activateModule', 'activateModule' );
|
35 |
$this->add_ajax_action( 'skipActivator', 'skipActivator' );
|
|
|
36 |
$this->add_filter( 'wdp_register_hub_action', 'addMyEndpoint' );
|
37 |
add_filter( 'custom_menu_order', '__return_true' );
|
38 |
$this->add_filter( 'menu_order', 'menuOrder' );
|
@@ -73,14 +74,25 @@ class Dashboard extends Controller {
|
|
73 |
return $menu_order;
|
74 |
}
|
75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
/**
|
77 |
* @param $actions
|
78 |
*
|
79 |
* @return mixed
|
80 |
*/
|
81 |
public function addMyEndpoint( $actions ) {
|
82 |
-
$actions['defender_new_scan']
|
83 |
-
$actions['defender_schedule_scan']
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
return $actions;
|
86 |
}
|
@@ -120,6 +132,114 @@ class Dashboard extends Controller {
|
|
120 |
wp_send_json_success();
|
121 |
}
|
122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
123 |
public function actionIndex() {
|
124 |
$this->render( 'dashboard' );
|
125 |
}
|
33 |
$this->add_ajax_action( 'toggleBlacklistWidget', 'toggleBlacklistWidget' );
|
34 |
$this->add_ajax_action( 'activateModule', 'activateModule' );
|
35 |
$this->add_ajax_action( 'skipActivator', 'skipActivator' );
|
36 |
+
$this->add_action( 'defenderSubmitStats', 'defenderSubmitStats' );
|
37 |
$this->add_filter( 'wdp_register_hub_action', 'addMyEndpoint' );
|
38 |
add_filter( 'custom_menu_order', '__return_true' );
|
39 |
$this->add_filter( 'menu_order', 'menuOrder' );
|
74 |
return $menu_order;
|
75 |
}
|
76 |
|
77 |
+
public function defenderSubmitStats() {
|
78 |
+
if ( $this->hasMethod( '_submitStatsToDev' ) ) {
|
79 |
+
$this->_submitStatsToDev();
|
80 |
+
}
|
81 |
+
}
|
82 |
+
|
83 |
/**
|
84 |
* @param $actions
|
85 |
*
|
86 |
* @return mixed
|
87 |
*/
|
88 |
public function addMyEndpoint( $actions ) {
|
89 |
+
$actions['defender_new_scan'] = array( &$this, 'new_scan' );
|
90 |
+
$actions['defender_schedule_scan'] = array( &$this, 'schedule_scan' );
|
91 |
+
$actions['defender_manage_audit_log'] = array( &$this, 'manage_audit_log' );
|
92 |
+
$actions['defender_manage_lockout'] = array( &$this, 'manage_lockout' );
|
93 |
+
$actions['defender_whitelist_ip'] = array( &$this, 'whitelist_ip' );
|
94 |
+
$actions['defender_blacklist_ip'] = array( &$this, 'blacklist_ip' );
|
95 |
+
$actions['defender_get_stats'] = array( &$this, 'get_stats' );
|
96 |
|
97 |
return $actions;
|
98 |
}
|
132 |
wp_send_json_success();
|
133 |
}
|
134 |
|
135 |
+
/**
|
136 |
+
* Hub Audit log endpoint
|
137 |
+
*
|
138 |
+
* @param $params
|
139 |
+
* @param $action
|
140 |
+
*/
|
141 |
+
public function manage_audit_log( $params, $action ) {
|
142 |
+
$response = null;
|
143 |
+
if ( class_exists( '\WP_Defender\Module\Audit\Model\Settings' ) ) {
|
144 |
+
$response = array();
|
145 |
+
$settings = \WP_Defender\Module\Audit\Model\Settings::instance();
|
146 |
+
if ( $settings->enabled == true ) {
|
147 |
+
$settings->enabled = false;
|
148 |
+
$response['enabled'] = false;
|
149 |
+
} else {
|
150 |
+
$settings->enabled = true;
|
151 |
+
$response['enabled'] = true;
|
152 |
+
}
|
153 |
+
$settings->save();
|
154 |
+
}
|
155 |
+
wp_send_json_success( $response );
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Hub Lockouts endpoint
|
160 |
+
*
|
161 |
+
* @param $params
|
162 |
+
* @param $action
|
163 |
+
*/
|
164 |
+
public function manage_lockout( $params, $action ) {
|
165 |
+
$type = $params['type'];
|
166 |
+
$settings = \WP_Defender\Module\IP_Lockout\Model\Settings::instance();
|
167 |
+
$response = array();
|
168 |
+
if ( $type == 'login' ) {
|
169 |
+
if ( $settings->login_protection ) {
|
170 |
+
$settings->login_protection = 0;
|
171 |
+
$response[ $type ] = 'disabled';
|
172 |
+
} else {
|
173 |
+
$settings->login_protection = 1;
|
174 |
+
$response[ $type ] = 'enabled';
|
175 |
+
}
|
176 |
+
$settings->save();
|
177 |
+
} else if ( $type == '404' ) {
|
178 |
+
if ( $settings->detect_404 ) {
|
179 |
+
$settings->detect_404 = 0;
|
180 |
+
$response[ $type ] = 'disabled';
|
181 |
+
} else {
|
182 |
+
$settings->detect_404 = 1;
|
183 |
+
$response[ $type ] = 'enabled';
|
184 |
+
}
|
185 |
+
$settings->save();
|
186 |
+
} else {
|
187 |
+
$response[ $type ] = 'invalid';
|
188 |
+
}
|
189 |
+
wp_send_json_success();
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Hub Whitelist IP endpoint
|
194 |
+
*
|
195 |
+
* @param $params
|
196 |
+
* @param $action
|
197 |
+
*/
|
198 |
+
public function whitelist_ip( $params, $action ) {
|
199 |
+
$settings = \WP_Defender\Module\IP_Lockout\Model\Settings::instance();
|
200 |
+
$ip = $params['ip'];
|
201 |
+
if ( $ip && filter_var( $ip, FILTER_VALIDATE_IP ) ) {
|
202 |
+
$settings->removeIpFromList( $ip, 'blacklist' );
|
203 |
+
$settings->addIpToList( $ip, 'whitelist' );
|
204 |
+
} else {
|
205 |
+
wp_send_json_error();
|
206 |
+
}
|
207 |
+
wp_send_json_success();
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Hub Blacklist IP endpoint
|
212 |
+
*
|
213 |
+
* @param $params
|
214 |
+
* @param $action
|
215 |
+
*/
|
216 |
+
public function blacklist_ip( $params, $action ) {
|
217 |
+
$settings = \WP_Defender\Module\IP_Lockout\Model\Settings::instance();
|
218 |
+
$ip = $params['ip'];
|
219 |
+
if ( $ip && filter_var( $ip, FILTER_VALIDATE_IP ) ) {
|
220 |
+
$settings->removeIpFromList( $ip, 'whitelist' );
|
221 |
+
$settings->addIpToList( $ip, 'blacklist' );
|
222 |
+
} else {
|
223 |
+
wp_send_json_error();
|
224 |
+
}
|
225 |
+
wp_send_json_success();
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Hub Stats endpoint
|
230 |
+
*
|
231 |
+
* @param $params
|
232 |
+
* @param $action
|
233 |
+
*/
|
234 |
+
public function get_stats( $params, $action ) {
|
235 |
+
$stats = Utils::instance()->generateStats();
|
236 |
+
wp_send_json_success(
|
237 |
+
array(
|
238 |
+
'stats' => $stats
|
239 |
+
)
|
240 |
+
);
|
241 |
+
}
|
242 |
+
|
243 |
public function actionIndex() {
|
244 |
$this->render( 'dashboard' );
|
245 |
}
|
app/module/advanced-tools.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Author: Hoang Ngo
|
4 |
+
*/
|
5 |
+
|
6 |
+
namespace WP_Defender\Module;
|
7 |
+
|
8 |
+
use Hammer\Base\Module;
|
9 |
+
use WP_Defender\Module\Advanced_Tools\Controller\Main;
|
10 |
+
|
11 |
+
class Advanced_Tools extends Module {
|
12 |
+
public function __construct() {
|
13 |
+
$main = new Main();
|
14 |
+
}
|
15 |
+
}
|
app/module/advanced-tools/component/auth-api.php
ADDED
@@ -0,0 +1,307 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Author: Hoang Ngo
|
4 |
+
*/
|
5 |
+
|
6 |
+
namespace WP_Defender\Module\Advanced_Tools\Component;
|
7 |
+
|
8 |
+
use Hammer\Base\Component;
|
9 |
+
use WP_Defender\Module\Advanced_Tools\Model\Auth_Settings;
|
10 |
+
|
11 |
+
class Auth_API extends Component {
|
12 |
+
/**
|
13 |
+
* @param int $length
|
14 |
+
*
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
public static function generateSecret( $length = 16 ) {
|
18 |
+
$strings = "ABCDEFGHIJKLMNOPQRSTUVWXYS234567";
|
19 |
+
$secret = array();
|
20 |
+
for ( $i = 0; $i < $length; $i ++ ) {
|
21 |
+
$secret[] = $strings[ rand( 0, strlen( $strings ) - 1 ) ];
|
22 |
+
}
|
23 |
+
|
24 |
+
return implode( "", $secret );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @param $name
|
29 |
+
* @param $secret
|
30 |
+
* @param int $width
|
31 |
+
* @param int $height
|
32 |
+
* @param null $title
|
33 |
+
*
|
34 |
+
* @return string
|
35 |
+
*/
|
36 |
+
public static function generateQRCode( $name, $secret, $width = 200, $height = 200, $title = null ) {
|
37 |
+
$chl = urlencode( 'otpauth://totp/' . $name . '?secret=' . $secret . '' );
|
38 |
+
if ( ! is_null( $title ) ) {
|
39 |
+
$chl .= urlencode( '&issuer=' . $title );
|
40 |
+
}
|
41 |
+
|
42 |
+
return "https://chart.googleapis.com/chart?cht=qr&chs={$width}x{$height}&chl=$chl&chld=M|0";
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Calculate the TOTP code
|
47 |
+
*
|
48 |
+
* @param $secret
|
49 |
+
* @param $counter
|
50 |
+
*
|
51 |
+
* @return \string
|
52 |
+
*
|
53 |
+
* reference: https://tools.ietf.org/html/rfc4226#section-5.3
|
54 |
+
* https://garbagecollected.org/2014/09/14/how-google-authenticator-works/
|
55 |
+
*/
|
56 |
+
public static function generateCode( $secret, $counter = null ) {
|
57 |
+
//secret should be base 32, as GA want it
|
58 |
+
include_once wp_defender()->getPluginPath() . 'vendor/binary-to-text-php/Base2n.php';
|
59 |
+
$base32 = new \Base2n( 5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', false, true, true );
|
60 |
+
$secret = $base32->decode( $secret );
|
61 |
+
//timestep fixed at 30
|
62 |
+
if ( is_null( $counter ) ) {
|
63 |
+
$counter = time();
|
64 |
+
}
|
65 |
+
$input = floor( $counter / 30 );
|
66 |
+
//according to https://tools.ietf.org/html/rfc4226#section-5.3, should be a 8 bytes value
|
67 |
+
$time = chr( 0 ) . chr( 0 ) . chr( 0 ) . chr( 0 ) . pack( 'N*', $input );
|
68 |
+
$hmac = hash_hmac( 'sha1', $time, $secret, true );
|
69 |
+
//now we have 20 bytes sha1, need to short it down
|
70 |
+
//getting last byte of the hmac
|
71 |
+
$offset = ord( substr( $hmac, - 1 ) ) & 0x0F;
|
72 |
+
$four_bytes = substr( $hmac, $offset, 4 );
|
73 |
+
//now convert it into INT
|
74 |
+
$value = unpack( 'N', $four_bytes );
|
75 |
+
$value = $value[1];
|
76 |
+
//make sure it always act like 32 bits
|
77 |
+
$value = $value & 0x7FFFFFFF;;
|
78 |
+
//we so close
|
79 |
+
$code = $value % pow( 10, 6 );
|
80 |
+
//in some case we have the 0 before, so it become lesser than 6, make sure it always right
|
81 |
+
$code = str_pad( $code, 6, '0', STR_PAD_LEFT );
|
82 |
+
|
83 |
+
return $code;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @param $secret
|
88 |
+
* @param $userCode
|
89 |
+
* @param int $window
|
90 |
+
*
|
91 |
+
* @return bool
|
92 |
+
*/
|
93 |
+
public static function compare( $secret, $userCode, $window = 1 ) {
|
94 |
+
if ( strlen( $userCode ) != 6 ) {
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* window is 30 seconds, before and after
|
100 |
+
*/
|
101 |
+
for ( $i = - $window; $i <= $window; $i ++ ) {
|
102 |
+
$counter = $i == 0 ? null : $i * 30 + time();
|
103 |
+
$code = self::generateCode( $secret, $counter );
|
104 |
+
if ( self::hasEqual( $code, $userCode ) ) {
|
105 |
+
return true;
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
return false;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Timing attack safe string comparison, replacement of has_equals which only on 5.6+
|
114 |
+
*
|
115 |
+
* @param $known_string
|
116 |
+
* @param $user_string
|
117 |
+
*
|
118 |
+
* @return bool
|
119 |
+
* reference: http://php.net/manual/en/function.hash-equals.php#119576
|
120 |
+
*/
|
121 |
+
private static function hasEqual( $known_string, $user_string ) {
|
122 |
+
if ( function_exists( 'hash_equals' ) ) {
|
123 |
+
return hash_equals( $known_string, $user_string );
|
124 |
+
}
|
125 |
+
|
126 |
+
$ret = 0;
|
127 |
+
|
128 |
+
if ( strlen( $known_string ) !== strlen( $user_string ) ) {
|
129 |
+
$user_string = $known_string;
|
130 |
+
$ret = 1;
|
131 |
+
}
|
132 |
+
|
133 |
+
$res = $known_string ^ $user_string;
|
134 |
+
|
135 |
+
for ( $i = strlen( $res ) - 1; $i >= 0; -- $i ) {
|
136 |
+
$ret |= ord( $res[ $i ] );
|
137 |
+
}
|
138 |
+
|
139 |
+
return ! $ret;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* @return bool
|
144 |
+
*/
|
145 |
+
public static function isEnableForCurrentRole( $user = null ) {
|
146 |
+
if ( $user == null ) {
|
147 |
+
$user = wp_get_current_user();
|
148 |
+
}
|
149 |
+
if ( ! $user instanceof \WP_User ) {
|
150 |
+
return false;
|
151 |
+
}
|
152 |
+
$settings = Auth_Settings::instance();
|
153 |
+
$allowedForThisRole = array_intersect( $settings->userRoles, $user->roles );
|
154 |
+
|
155 |
+
return count( $allowedForThisRole ) > 0;
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* @return bool|mixed|string
|
160 |
+
*/
|
161 |
+
public static function createSecretForCurrentUser() {
|
162 |
+
if ( ! is_user_logged_in() ) {
|
163 |
+
return false;
|
164 |
+
}
|
165 |
+
|
166 |
+
$secret = get_user_meta( get_current_user_id(), 'defenderAuthSecret', true );
|
167 |
+
if ( ! $secret ) {
|
168 |
+
$secret = self::generateSecret();
|
169 |
+
update_user_meta( get_current_user_id(), 'defenderAuthSecret', $secret );
|
170 |
+
}
|
171 |
+
|
172 |
+
return $secret;
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @param null $userID
|
177 |
+
*
|
178 |
+
* @return bool|mixed
|
179 |
+
*/
|
180 |
+
public static function getUserSecret( $userID = null ) {
|
181 |
+
if ( $userID == null ) {
|
182 |
+
$userID = get_current_user_id();
|
183 |
+
}
|
184 |
+
$secret = get_user_meta( $userID, 'defenderAuthSecret', true );
|
185 |
+
if ( ! $secret ) {
|
186 |
+
return false;
|
187 |
+
}
|
188 |
+
|
189 |
+
return $secret;
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* @param $userID
|
194 |
+
*
|
195 |
+
* @return mixed
|
196 |
+
*/
|
197 |
+
public static function isUserEnableOTP( $userID ) {
|
198 |
+
if ( $userID instanceof \WP_User ) {
|
199 |
+
$user = $userID;
|
200 |
+
$userID = $user->ID;
|
201 |
+
} else {
|
202 |
+
$user = get_user_by( 'id', $userID );
|
203 |
+
}
|
204 |
+
if ( ! self::isEnableForCurrentRole( $user ) ) {
|
205 |
+
return false;
|
206 |
+
}
|
207 |
+
|
208 |
+
$isOn = get_user_meta( $userID, 'defenderAuthOn', true );
|
209 |
+
|
210 |
+
return $isOn;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* @param $userID
|
215 |
+
*
|
216 |
+
* @return bool|mixed|string
|
217 |
+
*/
|
218 |
+
public static function getBackupEmail( $userID ) {
|
219 |
+
$email = get_user_meta( $userID, 'defenderAuthEmail', true );
|
220 |
+
if ( empty( $email ) ) {
|
221 |
+
$user = get_user_by( 'id', $userID );
|
222 |
+
if ( ! is_object( $user ) ) {
|
223 |
+
return false;
|
224 |
+
}
|
225 |
+
$email = $user->user_email;
|
226 |
+
}
|
227 |
+
|
228 |
+
return $email;
|
229 |
+
}
|
230 |
+
|
231 |
+
/**
|
232 |
+
* Generate single code, use in case lost phone
|
233 |
+
*
|
234 |
+
* @param $userID
|
235 |
+
*
|
236 |
+
* @return string
|
237 |
+
*/
|
238 |
+
public static function createBackupCode( $userID ) {
|
239 |
+
$code = wp_generate_password( 20, false );
|
240 |
+
update_user_meta( $userID, 'defenderBackupCode', array(
|
241 |
+
'code' => $code,
|
242 |
+
'time' => time()
|
243 |
+
) );
|
244 |
+
|
245 |
+
return $code;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* @return bool
|
250 |
+
*/
|
251 |
+
public static function isJetPackSSO() {
|
252 |
+
if ( is_plugin_active_for_network( 'jetpack/jetpack.php' ) ) {
|
253 |
+
//loop through all sites
|
254 |
+
$settings = Auth_Settings::instance();
|
255 |
+
$isConflict = $settings->isConflict( 'jetpack/jetpack.php' );
|
256 |
+
if ( $isConflict === 0 ) {
|
257 |
+
//no data, init
|
258 |
+
global $wpdb;
|
259 |
+
$sql = "SELECT blog_id FROM `{$wpdb->prefix}blogs`";
|
260 |
+
$blogs = $wpdb->get_col( $sql );
|
261 |
+
foreach ( $blogs as $id ) {
|
262 |
+
$options = get_blog_option( $id, 'jetpack_active_modules', array() );
|
263 |
+
if ( array_search( 'sso', $options ) ) {
|
264 |
+
$settings->markAsConflict( 'jetpack/jetpack.php' );
|
265 |
+
|
266 |
+
return true;
|
267 |
+
}
|
268 |
+
}
|
269 |
+
} else {
|
270 |
+
//get the data from cache
|
271 |
+
return $isConflict;
|
272 |
+
}
|
273 |
+
|
274 |
+
} elseif ( is_plugin_active( 'jetpack/jetpack.php' ) ) {
|
275 |
+
//ugly but faster
|
276 |
+
$settings = Auth_Settings::instance();
|
277 |
+
$isConflict = $settings->isConflict( 'jetpack/jetpack.php' );
|
278 |
+
if ( $isConflict === 0 ) {
|
279 |
+
$options = get_option( 'jetpack_active_modules', array() );
|
280 |
+
if ( array_search( 'sso', $options ) ) {
|
281 |
+
$settings->markAsConflict( 'jetpack/jetpack.php' );
|
282 |
+
|
283 |
+
return true;
|
284 |
+
}
|
285 |
+
} else {
|
286 |
+
return $isConflict;
|
287 |
+
}
|
288 |
+
|
289 |
+
}
|
290 |
+
|
291 |
+
return false;
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* @return bool
|
296 |
+
*/
|
297 |
+
public static function isTML() {
|
298 |
+
if ( is_plugin_active( 'theme-my-login/theme-my-login.php' ) || is_plugin_active_for_network( 'theme-my-login/theme-my-login.php' ) ) {
|
299 |
+
$settings = Auth_Settings::instance();
|
300 |
+
$settings->markAsConflict( 'theme-my-login/theme-my-login.php' );
|
301 |
+
|
302 |
+
return true;
|
303 |
+
}
|
304 |
+
|
305 |
+
return false;
|
306 |
+
}
|
307 |
+
}
|
app/module/advanced-tools/controller/main.php
ADDED
@@ -0,0 +1,463 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Author: Hoang Ngo
|
4 |
+
*/
|
5 |
+
|
6 |
+
namespace WP_Defender\Module\Advanced_Tools\Controller;
|
7 |
+
|
8 |
+
use Hammer\Helper\HTTP_Helper;
|
9 |
+
use Hammer\Helper\WP_Helper;
|
10 |
+
use WP_Defender\Behavior\Utils;
|
11 |
+
use WP_Defender\Controller;
|
12 |
+
use WP_Defender\Module\Advanced_Tools\Component\Auth_API;
|
13 |
+
use WP_Defender\Module\Advanced_Tools\Model\Auth_Settings;
|
14 |
+
|
15 |
+
class Main extends Controller {
|
16 |
+
protected $slug = 'wdf-advanced-tools';
|
17 |
+
protected $sessionToken;
|
18 |
+
public $layout = 'layout';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return array
|
22 |
+
*/
|
23 |
+
public function behaviors() {
|
24 |
+
return array(
|
25 |
+
'utils' => '\WP_Defender\Behavior\Utils'
|
26 |
+
);
|
27 |
+
}
|
28 |
+
|
29 |
+
public function __construct() {
|
30 |
+
if ( $this->is_network_activate( wp_defender()->plugin_slug ) ) {
|
31 |
+
$this->add_action( 'network_admin_menu', 'adminMenu' );
|
32 |
+
} else {
|
33 |
+
$this->add_action( 'admin_menu', 'adminMenu' );
|
34 |
+
}
|
35 |
+
|
36 |
+
if ( $this->isInPage() || $this->isDashboard() ) {
|
37 |
+
$this->add_action( 'defender_enqueue_assets', 'scripts', 11 );
|
38 |
+
}
|
39 |
+
$this->add_ajax_action( 'saveAdvancedSettings', 'saveSettings' );
|
40 |
+
$setting = Auth_Settings::instance();
|
41 |
+
if ( $setting->enabled ) {
|
42 |
+
$this->add_action( 'update_option_jetpack_available_modules', 'listenForJetpackOption', 10, 3 );
|
43 |
+
//prepare for the login part
|
44 |
+
$isJetpackSSO = Auth_API::isJetPackSSO();
|
45 |
+
$isTML = Auth_API::isTML();
|
46 |
+
if ( ! defined( 'DOING_AJAX' ) && ! $isJetpackSSO && ! $isTML ) {
|
47 |
+
/**
|
48 |
+
* hook into wordpress login, can't use authenticate hook as that badly conflict
|
49 |
+
*/
|
50 |
+
$this->add_action( 'wp_login', 'maybeShowOTPLogin', 50, 2 );
|
51 |
+
$this->add_action( 'login_form_defenderVerifyOTP', 'defenderVerifyOTP' );
|
52 |
+
$this->add_action( 'set_logged_in_cookie', 'storeSessionKey' );
|
53 |
+
/**
|
54 |
+
* end
|
55 |
+
*/
|
56 |
+
} else {
|
57 |
+
if ( $isJetpackSSO ) {
|
58 |
+
wp_defender()->global['compatibility'][] = __( "You enabled Jetpack WordPress.com login, so Defender will disable the 2 factors login for avoiding conflict", wp_defender()->domain );
|
59 |
+
}
|
60 |
+
if ( $isTML ) {
|
61 |
+
wp_defender()->global['compatibility'][] = __( "You enabled the plugin Theme My Login, so Defender will disable the 2 factors login for avoiding conflict", wp_defender()->domain );
|
62 |
+
}
|
63 |
+
}
|
64 |
+
$this->add_filter( 'ms_shortcode_ajax_login', 'm2NoAjax' );
|
65 |
+
$this->add_action( 'show_user_profile', 'showUsers2FactorActivation' );
|
66 |
+
$this->add_action( 'profile_update', 'saveBackupEmail' );
|
67 |
+
$this->add_ajax_action( 'defVerifyOTP', 'verifyConfigOTP' );
|
68 |
+
$this->add_ajax_action( 'defDisableOTP', 'disableOTP' );
|
69 |
+
$this->add_ajax_action( 'defRetrieveOTP', 'retrieveOTP', false, true );
|
70 |
+
if ( Utils::instance()->isActivatedSingle() ) {
|
71 |
+
$this->add_filter( 'manage_users_columns', 'alterUsersTable' );
|
72 |
+
$this->add_filter( 'manage_users_custom_column', 'alterUsersTableRow', 10, 3 );
|
73 |
+
} else {
|
74 |
+
$this->add_filter( 'wpmu_users_columns', 'alterUsersTable' );
|
75 |
+
$this->add_filter( 'manage_users_custom_column', 'alterUsersTableRow', 10, 3 );
|
76 |
+
}
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* We have some feature conflict with jetpack, so listen to know when Defender can on
|
82 |
+
*
|
83 |
+
* @param $old_value
|
84 |
+
* @param $value
|
85 |
+
* @param $option
|
86 |
+
*/
|
87 |
+
public function listenForJetpackOption( $old_value, $value, $option ) {
|
88 |
+
$settings = Auth_Settings::instance();
|
89 |
+
if ( array_search( 'sso', $value ) ) {
|
90 |
+
$settings->markAsConflict( 'jetpack/jetpack.php' );
|
91 |
+
} else {
|
92 |
+
$settings->markAsUnConflict( 'jetpack/jetpack.php' );
|
93 |
+
}
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Stop ajax login on membership 2
|
98 |
+
* @return bool
|
99 |
+
*/
|
100 |
+
public function m2NoAjax() {
|
101 |
+
return false;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Return 2 factor auth status
|
106 |
+
*
|
107 |
+
* @param $val
|
108 |
+
* @param $column_name
|
109 |
+
* @param $user_id
|
110 |
+
*
|
111 |
+
* @return string
|
112 |
+
*/
|
113 |
+
public function alterUsersTableRow( $val, $column_name, $user_id ) {
|
114 |
+
if ( $column_name != 'defAuth' ) {
|
115 |
+
return $val;
|
116 |
+
}
|
117 |
+
|
118 |
+
if ( Auth_API::isUserEnableOTP( $user_id ) ) {
|
119 |
+
return '<span class="def-oval oval-green"></span>';
|
120 |
+
}
|
121 |
+
|
122 |
+
return '<span class="def-oval"></span>';
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Add the auth column inside users on single site
|
127 |
+
*
|
128 |
+
* @param $columns
|
129 |
+
*
|
130 |
+
* @return mixed
|
131 |
+
*
|
132 |
+
*/
|
133 |
+
public function alterUsersTable( $columns ) {
|
134 |
+
$columns = array_slice( $columns, 0, count( $columns ) - 1 ) + array(
|
135 |
+
'defAuth' => __( "2 Factor", wp_defender()->domain )
|
136 |
+
) + array_slice( $columns, count( $columns ) - 1 );
|
137 |
+
|
138 |
+
return $columns;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Generate an email for backup otp
|
143 |
+
*/
|
144 |
+
public function retrieveOTP() {
|
145 |
+
if ( ! wp_verify_nonce( HTTP_Helper::retrieve_get( 'nonce' ), 'defRetrieveOTP' ) ) {
|
146 |
+
wp_send_json_error( array() );
|
147 |
+
}
|
148 |
+
|
149 |
+
$token = HTTP_Helper::retrieve_get( 'token' );
|
150 |
+
$query = new \WP_User_Query( array(
|
151 |
+
'meta_key' => 'defOTPLoginToken',
|
152 |
+
'meta_value' => $token
|
153 |
+
) );
|
154 |
+
$res = $query->get_results();
|
155 |
+
if ( empty( $res ) ) {
|
156 |
+
//no user
|
157 |
+
wp_send_json_error( array(
|
158 |
+
'message' => __( "Your token is invalid", wp_defender()->domain )
|
159 |
+
) );
|
160 |
+
}
|
161 |
+
|
162 |
+
$user = $res[0];
|
163 |
+
//create a backup code for this user
|
164 |
+
$code = Auth_API::createBackupCode( $user->ID );
|
165 |
+
//send email
|
166 |
+
$backupEmail = Auth_API::getBackupEmail( $user->ID );
|
167 |
+
//send
|
168 |
+
wp_mail( $backupEmail, 'Your OTP code', $code );
|
169 |
+
wp_send_json_success( array(
|
170 |
+
'message' => __( "Your code has been sent to your email.", wp_defender()->domain )
|
171 |
+
) );
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* disable OTP feature
|
176 |
+
*/
|
177 |
+
public function disableOTP() {
|
178 |
+
if ( ! is_user_logged_in() ) {
|
179 |
+
return;
|
180 |
+
}
|
181 |
+
|
182 |
+
update_user_meta( get_current_user_id(), 'defenderAuthOn', 0 );
|
183 |
+
wp_send_json_success();
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Saving backup email when profile saved
|
188 |
+
*
|
189 |
+
* @param $userID
|
190 |
+
*/
|
191 |
+
public function saveBackupEmail( $userID ) {
|
192 |
+
$email = HTTP_Helper::retrieve_post( 'def_backup_email' );
|
193 |
+
if ( $email && get_current_user_id() == $userID ) {
|
194 |
+
update_user_meta( $userID, 'defenderAuthEmail', $email );
|
195 |
+
}
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* An ajax function for verify the OTP user input when configuring the 2 factors
|
200 |
+
*/
|
201 |
+
public function verifyConfigOTP() {
|
202 |
+
if ( ! wp_verify_nonce( HTTP_Helper::retrieve_post( 'nonce' ), 'defVerifyOTP' ) ) {
|
203 |
+
return;
|
204 |
+
}
|
205 |
+
|
206 |
+
if ( ! is_user_logged_in() ) {
|
207 |
+
return;
|
208 |
+
}
|
209 |
+
|
210 |
+
$otp = HTTP_Helper::retrieve_post( 'otp' );
|
211 |
+
$otp = trim( $otp );
|
212 |
+
if ( strlen( $otp ) == 0 ) {
|
213 |
+
wp_send_json_error( array(
|
214 |
+
'message' => __( "Please input a valid OTP code", wp_defender()->domain )
|
215 |
+
) );
|
216 |
+
}
|
217 |
+
|
218 |
+
$secret = Auth_API::getUserSecret();
|
219 |
+
//at this stage, secret should have value, do not need to check
|
220 |
+
$res = Auth_API::compare( $secret, $otp );
|
221 |
+
if ( $res ) {
|
222 |
+
//save it
|
223 |
+
update_user_meta( get_current_user_id(), 'defenderAuthOn', 1 );
|
224 |
+
wp_send_json_success();
|
225 |
+
} else {
|
226 |
+
//now need to check if the current user have backup otp
|
227 |
+
wp_send_json_error( array(
|
228 |
+
'message' => __( "Your OTP code is incorrect. Please try again.", wp_defender()->domain )
|
229 |
+
) );
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Show an section inside my profile page for user can activate 2 factor login
|
235 |
+
*
|
236 |
+
* @param $profileuser
|
237 |
+
*/
|
238 |
+
public function showUsers2FactorActivation( $profileuser ) {
|
239 |
+
if ( ! Auth_API::isEnableForCurrentRole() ) {
|
240 |
+
return;
|
241 |
+
}
|
242 |
+
|
243 |
+
$isOn = get_user_meta( $profileuser->ID, 'defenderAuthOn', true );
|
244 |
+
wp_enqueue_style( 'defAuth', wp_defender()->getPluginUrl() . 'app/module/advanced-tools/css/login-admin.css' );
|
245 |
+
$secretKey = Auth_API::createSecretForCurrentUser();
|
246 |
+
if ( $isOn && $isOn == 1 ) {
|
247 |
+
$email = Auth_API::getBackupEmail( $profileuser->ID );
|
248 |
+
$this->renderPartial( 'login/enabled', array(
|
249 |
+
'email' => $email
|
250 |
+
) );
|
251 |
+
} else {
|
252 |
+
//show the screen
|
253 |
+
$this->renderPartial( 'login/disabled', array(
|
254 |
+
'secretKey' => $secretKey
|
255 |
+
) );
|
256 |
+
}
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* We will check and show the OTP screen if user signon successfully
|
261 |
+
*
|
262 |
+
* @param $userLogin
|
263 |
+
* @param $user
|
264 |
+
*/
|
265 |
+
public function maybeShowOTPLogin( $userLogin, $user ) {
|
266 |
+
if ( ! Auth_API::isUserEnableOTP( $user->ID ) ) {
|
267 |
+
//no enable, then just return
|
268 |
+
return;
|
269 |
+
}
|
270 |
+
|
271 |
+
//clean up session and auth cookies for preventing
|
272 |
+
$token = $this->sessionToken;
|
273 |
+
if ( $token ) {
|
274 |
+
$sManager = \WP_Session_Tokens::get_instance( $user->ID );
|
275 |
+
$sManager->destroy( $token );
|
276 |
+
}
|
277 |
+
wp_clear_auth_cookie();
|
278 |
+
|
279 |
+
$this->showOTPScreen( $user );
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* verify OTP code which user input in order to login
|
284 |
+
*/
|
285 |
+
public function defenderVerifyOTP() {
|
286 |
+
if ( ( $otp = HTTP_Helper::retrieve_post( 'otp', null ) ) != null ) {
|
287 |
+
$params = array();
|
288 |
+
if ( ! wp_verify_nonce( HTTP_Helper::retrieve_post( '_wpnonce' ), 'DefOtpCheck' ) ) {
|
289 |
+
$params['error'] = new \WP_Error( 'security_fail', __( "Some error happen", wp_defender()->domain ) );
|
290 |
+
}
|
291 |
+
|
292 |
+
$login_token = HTTP_Helper::retrieve_post( 'login_token' );
|
293 |
+
$query = new \WP_User_Query( array(
|
294 |
+
'meta_key' => 'defOTPLoginToken',
|
295 |
+
'meta_value' => $login_token
|
296 |
+
) );
|
297 |
+
$res = $query->get_results();
|
298 |
+
if ( empty( $res ) ) {
|
299 |
+
//no users, redirect to the login page immediatly
|
300 |
+
wp_redirect( site_url( 'wp-login.php', 'login_post' ) );
|
301 |
+
exit;
|
302 |
+
} else {
|
303 |
+
$user = $res[0];
|
304 |
+
$secret = Auth_API::getUserSecret( $user->ID );
|
305 |
+
$redirect = HTTP_Helper::retrieve_post( 'redirect_to', admin_url() );
|
306 |
+
if ( empty( $redirect ) ) {
|
307 |
+
$redirect = admin_url();
|
308 |
+
}
|
309 |
+
if ( Auth_API::compare( $secret, $otp ) ) {
|
310 |
+
//sign in
|
311 |
+
delete_user_meta( $user->ID, 'defOTPLoginToken' );
|
312 |
+
wp_set_current_user( $user->ID, $user->user_login );
|
313 |
+
wp_set_auth_cookie( $user->ID, true );
|
314 |
+
wp_redirect( $redirect );
|
315 |
+
exit;
|
316 |
+
} else {
|
317 |
+
$backupCode = get_user_meta( $user->ID, 'defenderBackupCode', true );
|
318 |
+
if ( $backupCode && $backupCode['code'] == $otp && strtotime( '+3 minutes', $backupCode['time'] ) > time() ) {
|
319 |
+
delete_user_meta( $user->ID, 'defOTPLoginToken' );
|
320 |
+
delete_user_meta( $user->ID, 'defenderBackupCode' );
|
321 |
+
wp_set_current_user( $user->ID, $user->user_login );
|
322 |
+
wp_set_auth_cookie( $user->ID, true );
|
323 |
+
wp_redirect( $redirect );
|
324 |
+
exit;
|
325 |
+
} else {
|
326 |
+
$params['error'] = new \WP_Error( 'opt_fail', __( "Whoops, the passcode you entered was incorrect or expired.", wp_defender()->domain ) );
|
327 |
+
$this->showOTPScreen( $user, $params );
|
328 |
+
}
|
329 |
+
}
|
330 |
+
}
|
331 |
+
}
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Show the OTP screen
|
336 |
+
*
|
337 |
+
* @param $user
|
338 |
+
* @param $params
|
339 |
+
*/
|
340 |
+
private function showOTPScreen( $user, $params = array() ) {
|
341 |
+
//now show the OTP screen
|
342 |
+
$this->add_action( 'login_enqueue_scripts', 'includeAuthStyles' );
|
343 |
+
wp_enqueue_script( 'jquery' );
|
344 |
+
$params['loginToken'] = $this->createLoginToken( $user );
|
345 |
+
$params['redirect_to'] = HTTP_Helper::retrieve_post( 'redirect_to' );
|
346 |
+
if ( ! isset( $params['error'] ) ) {
|
347 |
+
$params['error'] = null;
|
348 |
+
}
|
349 |
+
//if this goes here then the current user is ok, need to show the 2 auth
|
350 |
+
$this->renderPartial( 'login/otp', $params );
|
351 |
+
exit;
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* We will empty all auth cookies or session, so should not rely on wp_get_session_token
|
356 |
+
*
|
357 |
+
* @param $cookie
|
358 |
+
*/
|
359 |
+
public function storeSessionKey( $cookie ) {
|
360 |
+
$cookie = wp_parse_auth_cookie( $cookie, 'logged_in' );
|
361 |
+
$this->sessionToken = ! empty( $cookie['token'] ) ? $cookie['token'] : '';
|
362 |
+
}
|
363 |
+
|
364 |
+
/**
|
365 |
+
* Create a unique token to retrieve user later
|
366 |
+
*
|
367 |
+
* @param $user
|
368 |
+
*
|
369 |
+
* @return string
|
370 |
+
*/
|
371 |
+
private function createLoginToken( $user ) {
|
372 |
+
$tmp = uniqid();
|
373 |
+
// create and store a login token so we can query this user again
|
374 |
+
update_user_meta( $user->ID, 'defOTPLoginToken', $tmp );
|
375 |
+
|
376 |
+
return $tmp;
|
377 |
+
}
|
378 |
+
|
379 |
+
/**
|
380 |
+
* add css for OTP page
|
381 |
+
*/
|
382 |
+
public function includeAuthStyles() {
|
383 |
+
//enqueue css here
|
384 |
+
wp_enqueue_style( 'defAuth', wp_defender()->getPluginUrl() . 'app/module/advanced-tools/css/login.css' );
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Add submit admin page
|
389 |
+
*/
|
390 |
+
public function adminMenu() {
|
391 |
+
$cap = is_multisite() ? 'manage_network_options' : 'manage_options';
|
392 |
+
add_submenu_page( 'wp-defender', esc_html__( "Advanced Tools", wp_defender()->domain ), esc_html__( "Advanced Tools", wp_defender()->domain ), $cap, $this->slug, array(
|
393 |
+
&$this,
|
394 |
+
'actionIndex'
|
395 |
+
) );
|
396 |
+
}
|
397 |
+
|
398 |
+
/**
|
399 |
+
* a simple router
|
400 |
+
*/
|
401 |
+
public function actionIndex() {
|
402 |
+
$view = HTTP_Helper::retrieve_get( 'view' );
|
403 |
+
switch ( $view ) {
|
404 |
+
default:
|
405 |
+
$this->viewAuth();
|
406 |
+
break;
|
407 |
+
}
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* View the 2 factor main admin page
|
412 |
+
*/
|
413 |
+
public function viewAuth() {
|
414 |
+
$settings = Auth_Settings::instance();
|
415 |
+
if ( $settings->enabled == false ) {
|
416 |
+
$this->render( 'disabled' );
|
417 |
+
} else {
|
418 |
+
$this->render( 'main', array(
|
419 |
+
'settings' => $settings
|
420 |
+
) );
|
421 |
+
}
|
422 |
+
}
|
423 |
+
|
424 |
+
/**
|
425 |
+
* Enqueue scripts & styles
|
426 |
+
*/
|
427 |
+
public function scripts() {
|
428 |
+
if ( $this->isInPage() ) {
|
429 |
+
\WDEV_Plugin_Ui::load( wp_defender()->getPluginUrl() . 'shared-ui/' );
|
430 |
+
wp_enqueue_script( 'defender' );
|
431 |
+
wp_enqueue_style( 'defender' );
|
432 |
+
wp_enqueue_script( 'adtools', wp_defender()->getPluginUrl() . 'app/module/advanced-tools/js/scripts.js' );
|
433 |
+
}
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Saving settings in admin area
|
438 |
+
*/
|
439 |
+
public function saveSettings() {
|
440 |
+
if ( ! $this->checkPermission() ) {
|
441 |
+
return;
|
442 |
+
}
|
443 |
+
|
444 |
+
if ( ! wp_verify_nonce( HTTP_Helper::retrieve_post( '_wpnonce' ), 'saveAdvancedSettings' ) ) {
|
445 |
+
return;
|
446 |
+
}
|
447 |
+
|
448 |
+
$data = $_POST;
|
449 |
+
$setting = Auth_Settings::instance();
|
450 |
+
$tmp = $setting->enabled;
|
451 |
+
$setting->import( $data );
|
452 |
+
$setting->save();
|
453 |
+
|
454 |
+
$res = array(
|
455 |
+
'message' => __( "Your settings have been updated.", wp_defender()->domain )
|
456 |
+
);
|
457 |
+
if ( $tmp != $setting->enabled ) {
|
458 |
+
$res['reload'] = 1;
|
459 |
+
}
|
460 |
+
|
461 |
+
wp_send_json_success( $res );
|
462 |
+
}
|
463 |
+
}
|
app/module/advanced-tools/css/login-admin.css
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.def-notification {
|
2 |
+
padding: 10px 20px;
|
3 |
+
border-radius: 4px;
|
4 |
+
background-color: #D1F1EA;
|
5 |
+
color: #666;
|
6 |
+
display: block;
|
7 |
+
clear: right;
|
8 |
+
width: 50%;
|
9 |
+
margin-bottom: 10px;
|
10 |
+
}
|
11 |
+
|
12 |
+
.card {
|
13 |
+
margin-top: 10px;
|
14 |
+
padding: 30px 30px;
|
15 |
+
}
|
16 |
+
|
17 |
+
.well {
|
18 |
+
border-radius: 5px;
|
19 |
+
background-color: #F9F9F9;
|
20 |
+
padding: 15px;
|
21 |
+
margin-top: 15px;
|
22 |
+
width: 50%;
|
23 |
+
}
|
24 |
+
|
25 |
+
.line {
|
26 |
+
margin-bottom: 20px;
|
27 |
+
}
|
28 |
+
|
29 |
+
.error {
|
30 |
+
color: #FF6D6D;
|
31 |
+
font-size: 12px !important;
|
32 |
+
font-weight: 500;
|
33 |
+
padding-bottom: 10px;
|
34 |
+
}
|
app/module/advanced-tools/css/login.css
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
body.login div#login h1 a {
|
2 |
+
background-image: url("../img/2factor-disabled.svg");
|
3 |
+
}
|
4 |
+
|
5 |
+
body.login div#login form {
|
6 |
+
padding-bottom: 26px;
|
7 |
+
}
|
8 |
+
|
9 |
+
.float-r {
|
10 |
+
float: right;
|
11 |
+
}
|
12 |
+
|
13 |
+
.clearfix {
|
14 |
+
clear: both;
|
15 |
+
}
|
16 |
+
|
17 |
+
.def-ajaxloader {
|
18 |
+
width: 20px;
|
19 |
+
position: relative;
|
20 |
+
top: 5px;
|
21 |
+
}
|
app/module/advanced-tools/img/2factor-disabled.svg
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2 |
+
<svg width="128px" height="128px" viewBox="0 0 128 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
3 |
+
<!-- Generator: Sketch 45.1 (43504) - http://www.bohemiancoding.com/sketch -->
|
4 |
+
<title>graphic-defender-2factor-disabled</title>
|
5 |
+
<desc>Created with Sketch.</desc>
|
6 |
+
<defs>
|
7 |
+
<circle id="path-1" cx="64" cy="64" r="64"></circle>
|
8 |
+
<polygon id="path-3" points="0.327466846 0.3500558 3.88734603 0.3500558 3.88734603 21.3428699 0.327466846 21.3428699 0.327466846 0.3500558"></polygon>
|
9 |
+
<polygon id="path-5" points="51.1257801 0.184853857 51.1257801 49.0738103 0.330536413 49.0738103 0.330536413 0.184853857"></polygon>
|
10 |
+
</defs>
|
11 |
+
<g id="Security-Plugin" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
12 |
+
<g id="Advanced-Tools---2-Factor---Disabled" transform="translate(-726.000000, -223.000000)">
|
13 |
+
<g id="graphic-defender-2factor-disabled" transform="translate(726.000000, 223.000000)">
|
14 |
+
<mask id="mask-2" fill="white">
|
15 |
+
<use xlink:href="#path-1"></use>
|
16 |
+
</mask>
|
17 |
+
<use id="mask" fill="#333333" xlink:href="#path-1"></use>
|
18 |
+
<g id="graphic" mask="url(#mask-2)">
|
19 |
+
<g transform="translate(-6.000000, 10.000000)">
|
20 |
+
<path d="M39.4062404,173.10829 C44.5020972,174.081424 53.4377494,173.063861 54.0267519,168.804431 C53.575243,166.584784 53.2010742,166.272707 53.2010742,166.272707 C53.2010742,166.272707 66.6772379,143.156842 65.7953453,123.921688 C64.9134527,104.686534 45.3095141,107.332196 45.3095141,107.332196 C45.3095141,107.332196 37.373913,118.626064 34.904757,136.272889 C32.4359591,153.919715 37.417954,162.29669 37.417954,162.29669 C37.417954,162.29669 35.7354476,166.837383 34.6032737,173.249817 C34.7436317,172.456549 34.891867,171.690869 35.044399,170.959585 C35.3802558,171.617418 36.4050128,172.535016 39.4062404,173.10829" id="Fill-19" fill="#9F5622"></path>
|
21 |
+
<path d="M98.7215192,173.10829 C93.6256624,174.081424 84.6900102,173.063861 84.1006496,168.804431 C84.5525166,166.584784 84.9266854,166.272707 84.9266854,166.272707 C84.9266854,166.272707 71.4505217,143.156842 72.3324143,123.921688 C73.2143069,104.686534 92.8182455,107.332196 92.8182455,107.332196 C92.8182455,107.332196 100.753847,118.626064 103.223003,136.272889 C105.691801,153.919715 100.709806,162.29669 100.709806,162.29669 C100.709806,162.29669 102.392312,166.837383 103.524486,173.249817 C103.384128,172.456549 103.235893,171.690869 103.083361,170.959585 C102.747504,171.617418 101.722747,172.535016 98.7215192,173.10829" id="Fill-77" fill="#9F5622"></path>
|
22 |
+
<path d="M45.5730793,111.169696 C44.4412634,111.145332 43.5396777,111.197643 42.9821841,111.245655 C42.9291918,111.344187 42.8747673,111.447376 42.8207008,111.549132 C45.055688,112.721121 54.9878107,118.292633 62.1181432,128.225332 C63.6098056,130.696504 64.5615192,132.467564 65.1673504,133.735218 C65.5007008,131.627717 65.7244859,129.513409 65.8032583,127.424898 C60.5981944,123.105273 50.4301125,115.602542 45.5730793,111.169696" id="Fill-123" fill="#98480C"></path>
|
23 |
+
<path d="M95.3429003,111.617065 C95.2684246,111.475897 95.1939488,111.334728 95.1216215,111.200725 C91.5313913,110.649665 73.9902148,108.978569 72.3789616,128.537265 C72.495688,130.435162 72.7262762,132.348825 73.0445882,134.254963 C74.7668389,130.825706 78.878399,123.432255 86.114,117.877224 C91.3011611,113.894757 94.0055601,112.275973 95.3429003,111.617065" id="Fill-125" fill="#98480C"></path>
|
24 |
+
<path d="M100.613739,76.4418678 C106.021821,71.862837 111.178547,67.119348 111.178547,67.119348 L111.178547,70.2465609 C119.016399,59.9806461 122.406118,48.4047988 122.238905,47.40121 C122.0409,46.2105903 119.117013,44.801768 115.563662,39.7637592 C102.081412,32.6214743 69.0639693,25.4283113 69.0639693,25.4283113 C69.0639693,25.4283113 38.0946087,33.1162819 24.6123581,40.2589251 C19.0610537,41.4491865 16.0870384,46.2105903 15.8886752,47.40121 C15.7228951,48.3961997 19.056399,59.7882408 26.7553248,69.9896623 L28.2978312,69.1609222 L36.5098517,74.7177445 L31.6094936,75.5826725 C31.6728696,75.6457327 31.7355294,75.7095095 31.7996215,75.7722115 C34.3769105,77.9549545 35.7650946,78.1530925 35.7650946,78.1530925 C35.7650946,78.1530925 39.7799795,83.113351 42.1592634,84.5021087 C49.0983939,85.69237 69.0639693,85.2437827 69.0639693,85.2437827 C69.0639693,85.2437827 89.0291867,85.69237 95.9686752,84.5021087 C98.3479591,83.113351 102.362844,78.1530925 102.362844,78.1530925 C102.362844,78.1530925 102.51645,78.1298032 102.810414,78.0230308 C100.344123,78.2670308 98.7471918,78.0223142 100.613739,76.4418678" id="Fill-127" fill="#9F5622"></path>
|
25 |
+
<path d="M82.4067212,34.5627971 L69.0637545,31.4660394 L55.7211458,34.5627971 L55.499509,37.0296693 C55.499509,37.0296693 60.1549565,40.9662743 62.0845217,42.1733756 C64.014087,43.3804769 65.8169003,45.3865797 65.8169003,45.3865797 L66.623601,45.9931759 L69.0637545,45.9931759 L71.504266,45.9931759 L72.3109668,45.3865797 C72.3109668,45.3865797 74.1137801,43.3804769 76.0433453,42.1733756 C77.9729105,40.9662743 82.6283581,37.0296693 82.6283581,37.0296693 L82.4067212,34.5627971 Z" id="Fill-129" fill="#98480C"></path>
|
26 |
+
<path d="M68.0702916,21.3509674 C67.9360205,19.1470849 67.4053811,10.2917838 67.2954578,6.37237709 C67.2199079,3.67010396 67.526046,1.65253568 67.7824143,0.467290455 C66.6745882,0.59090279 64.8008798,0.851026138 61.97689,1.39993656 C56.8996522,2.38740206 54.2400102,7.87149016 54.2400102,10.2297985 C54.2400102,10.8908558 54.3234373,13.0567589 54.4491151,15.8432317 C54.0899847,16.1409762 53.6216471,16.6067618 53.5629258,17.0546326 C53.5396522,17.2334226 53.5503939,17.6859512 53.5840512,18.2839483 C54.0459437,18.8876781 54.4791918,19.419032 54.620624,19.4867501 C54.9657903,19.6515665 57.1918261,24.4624153 59.2427724,26.2796957 C60.7566343,27.6215166 62.5981176,28.5348147 63.6006752,28.9748029 C63.6364808,28.837217 63.6726445,28.6996311 63.7095243,28.5631201 C64.6053811,25.2481598 66.7372481,22.5136399 68.0702916,21.3509674" id="Fill-131" fill="#FF5B0C"></path>
|
27 |
+
<path d="M60.4257545,37.7939518 C61.9381841,38.0959959 62.4806394,33.2980458 63.6006394,28.9748388 C62.5980818,28.5348505 60.7565985,27.6215524 59.2427366,26.2797316 C57.1917903,24.4624511 54.9657545,19.6516023 54.6205882,19.4867859 C54.479156,19.4190678 54.0459079,18.8873557 53.5843734,18.2839841 C53.6896419,20.1528593 54.0201279,23.4516963 54.2399744,24.3241486 C54.4308184,25.0815877 54.7480563,25.5523894 54.943555,25.7877903 C55.1963427,30.4553204 55.4437596,34.4015994 55.5458056,34.6309093 C55.6782864,34.9297286 60.6420205,37.9225803 60.4257545,37.7939518" id="Fill-133" fill="#FFBC00"></path>
|
28 |
+
<path d="M70.0574322,21.3509674 C70.1917033,19.1470849 70.7223427,10.2917838 70.832266,6.37237709 C70.9078159,3.67010396 70.6016777,1.65253568 70.3453095,0.467290455 C71.4531355,0.59090279 73.326844,0.851026138 76.1508338,1.39993656 C81.2280716,2.38740206 83.8877136,7.87149016 83.8877136,10.2297985 C83.8877136,10.8908558 83.8042864,13.0567589 83.6786087,15.8432317 C84.0377391,16.1409762 84.5060767,16.6067618 84.564798,17.0546326 C84.5880716,17.2334226 84.5773299,17.6859512 84.5436726,18.2839483 C84.0817801,18.8876781 83.648532,19.419032 83.5070997,19.4867501 C83.1619335,19.6515665 80.9358977,24.4624153 78.8849514,26.2796957 C77.3710895,27.6215166 75.5296061,28.5348147 74.5270486,28.9748029 C74.491243,28.837217 74.4550793,28.6996311 74.4181995,28.5631201 C73.5223427,25.2481598 71.3904757,22.5136399 70.0574322,21.3509674" id="Fill-135" fill="#FF5B0C"></path>
|
29 |
+
<g id="Group-139" stroke-width="1" fill="none" transform="translate(66.956522, 0.008241)">
|
30 |
+
<mask id="mask-4" fill="white">
|
31 |
+
<use xlink:href="#path-3"></use>
|
32 |
+
</mask>
|
33 |
+
<g id="Clip-138"></g>
|
34 |
+
<path d="M3.38871611,0.459192952 C2.50431714,0.361019677 2.10723274,0.349912482 2.10723274,0.349912482 C2.10723274,0.349912482 1.71050639,0.361019677 0.826107417,0.459192952 C0.569381074,1.64443818 0.263601023,3.66200646 0.339150895,6.36392129 C0.449074169,10.2836863 0.979713555,19.1386291 1.1136266,21.3428699 C1.55976471,20.9537598 1.91638875,20.7405733 2.10723274,20.7405733 C2.29843478,20.7405733 2.65505882,20.9537598 3.10083887,21.3428699 C3.23510997,19.1386291 3.76574936,10.2836863 3.87567263,6.36392129 C3.95122251,3.66200646 3.6450844,1.64443818 3.38871611,0.459192952" id="Fill-137" fill="#FFBC00" mask="url(#mask-4)"></path>
|
35 |
+
</g>
|
36 |
+
<path d="M63.7094527,29.1566743 C64.6053095,25.841714 66.7371765,23.1071941 68.0702199,21.9445216 C68.5163581,21.5554115 68.8729821,21.342225 69.0638261,21.342225 C69.2546701,21.342225 69.6112941,21.5554115 70.0574322,21.9445216 C71.3904757,23.1071941 73.5223427,25.841714 74.4181995,29.1566743 C74.4550793,29.2931853 74.491243,29.4304129 74.5270486,29.5683571 C75.471601,33.2143836 76.0054629,37.1982837 77.0567161,38.1753586 C77.2002967,38.0908006 77.3413708,38.0080341 77.4860256,37.9224012 C77.5579949,37.8797639 77.6299642,37.8367683 77.7019335,37.7937727 C76.1895038,38.096175 75.6470486,33.2978667 74.5270486,28.9746596 C74.491243,28.8370737 74.4550793,28.6998461 74.4181995,28.5629768 C73.5223427,25.2480164 71.3904757,22.5134966 70.0574322,21.3508241 C69.6112941,20.9620722 69.2546701,20.7488858 69.0638261,20.7488858 C68.8729821,20.7488858 68.5163581,20.9620722 68.0702199,21.3508241 C66.7371765,22.5134966 64.6053095,25.2480164 63.7094527,28.5629768 C63.6725729,28.6998461 63.6364092,28.8370737 63.6006036,28.9746596 C62.4806036,33.2978667 61.9381483,38.096175 60.4257187,37.7937727 C60.497688,37.8367683 60.5696573,37.8797639 60.6419847,37.9224012 C60.7862813,38.0080341 60.9273555,38.0908006 61.0709361,38.1753586 C62.1221893,37.1982837 62.6560512,33.2143836 63.6006036,29.5683571 C63.6364092,29.4304129 63.6725729,29.2931853 63.7094527,29.1566743" id="Fill-140" fill="#98480C"></path>
|
37 |
+
<path d="M62.1412379,38.8049932 C62.167734,38.8204 62.1938721,38.8358068 62.2207263,38.8512135 C62.3263529,38.9128405 62.4305473,38.973751 62.5336675,39.0339448 C62.5648184,39.0518596 62.5959693,39.0701327 62.6267621,39.0880476 C62.7220051,39.1432253 62.8154578,39.1976863 62.9078363,39.2514308 C62.9414936,39.2707789 62.975867,39.2904852 63.0091662,39.3098332 C63.249422,39.4492106 63.4789361,39.5817803 63.6941279,39.7053927 C63.7188338,39.7197245 63.7424655,39.7329815 63.7668133,39.7469551 C63.8502404,39.7949668 63.9318772,39.8419037 64.0106496,39.8866907 C64.0378619,39.9024558 64.0647161,39.9175043 64.0912123,39.932911 C64.1606752,39.9723236 64.2272737,40.0103031 64.2920818,40.0475659 C64.3232327,40.0651225 64.3550997,40.0830373 64.3851765,40.1002355 C64.4507008,40.1374984 64.5126445,40.1726115 64.573156,40.2070079 C64.5928491,40.2181151 64.6146905,40.2306555 64.6340256,40.2414044 C64.713156,40.2861915 64.7876317,40.3277539 64.8563785,40.3664499 C64.8678363,40.3728993 64.8775038,40.3782737 64.8886036,40.3843648 C64.9430281,40.41482 64.9938721,40.4434837 65.0407775,40.4692811 C65.0608286,40.4803883 65.0787315,40.4904206 65.0973504,40.5004529 C65.1320818,40.5198009 65.1639488,40.5373574 65.1936675,40.5534808 C65.2108542,40.5627965 65.2273248,40.5717539 65.2427212,40.5799947 C65.2695754,40.5946849 65.2928491,40.6072253 65.3143325,40.6183325 C65.3250742,40.6240652 65.3372481,40.6305145 65.3469156,40.6355307 C65.3741279,40.6495043 65.3966854,40.6609698 65.4102916,40.6674191 C65.8940256,40.8866966 69.0638977,40.9963354 69.0638977,40.9963354 C69.0638977,40.9963354 72.2337698,40.8866966 72.7175038,40.6674191 C72.73111,40.6609698 72.7536675,40.6495043 72.7808798,40.6355307 C72.7905473,40.6305145 72.8027212,40.6240652 72.8134629,40.6183325 C72.8349463,40.6072253 72.8582199,40.5946849 72.8850742,40.5799947 C72.9004706,40.5717539 72.9169412,40.5627965 72.9341279,40.5534808 C72.9638465,40.5373574 72.9957136,40.5198009 73.030445,40.5004529 C73.0490639,40.4904206 73.0669668,40.4803883 73.0870179,40.4692811 C73.1339233,40.4434837 73.1847673,40.41482 73.2391918,40.3843648 C73.2502916,40.3782737 73.2599591,40.3728993 73.2714169,40.3664499 C73.3401637,40.3277539 73.4146394,40.2861915 73.4937698,40.2414044 C73.5131049,40.2306555 73.5345882,40.2181151 73.5546394,40.2070079 C73.6151509,40.1726115 73.6770946,40.1374984 73.7426189,40.1002355 C73.7726957,40.0830373 73.8045627,40.0651225 73.8357136,40.0475659 C73.9005217,40.0103031 73.9671202,39.9723236 74.0365831,39.932911 C74.0630793,39.9175043 74.0899335,39.9024558 74.1171458,39.8866907 C74.1959182,39.8419037 74.277555,39.7949668 74.3609821,39.7469551 C74.3853299,39.7329815 74.4089616,39.7197245 74.4336675,39.7053927 C74.6488593,39.5817803 74.8783734,39.4492106 75.1186292,39.3098332 C75.1519284,39.2904852 75.1863018,39.2707789 75.2199591,39.2514308 C75.3123376,39.1976863 75.4057903,39.1432253 75.5010332,39.0880476 C75.5318261,39.0701327 75.562977,39.0518596 75.5941279,39.0339448 C75.6972481,38.973751 75.8014425,38.9128405 75.9070691,38.8512135 C75.9339233,38.8358068 75.9600614,38.8204 75.9865575,38.8049932 C76.1265575,38.7229433 76.2687059,38.6401768 76.4119284,38.5559771 C76.6231816,38.4320065 76.8408798,38.3030197 77.0567877,38.1754661 C76.0055345,37.1983912 75.4716726,33.214491 74.5271202,29.5684646 C74.4913146,29.4305204 74.4551509,29.2932928 74.4182711,29.1567818 C73.5224143,25.8418214 71.3905473,23.1073016 70.0575038,21.9446291 C69.6113657,21.5555189 69.2547417,21.3423325 69.0638977,21.3423325 C68.8730537,21.3423325 68.5164297,21.5555189 68.0702916,21.9446291 C66.7372481,23.1073016 64.6053811,25.8418214 63.7095243,29.1567818 C63.6726445,29.2932928 63.6364808,29.4305204 63.6006752,29.5684646 C62.6561228,33.214491 62.1222609,37.1983912 61.0710077,38.1754661 C61.2869156,38.3030197 61.5046138,38.4320065 61.715867,38.5559771 C61.8590895,38.6401768 62.0012379,38.7229433 62.1412379,38.8049932" id="Fill-142" fill="#9F5622"></path>
|
38 |
+
<path d="M77.7019693,37.7939518 C76.1895396,38.0959959 75.6470844,33.2980458 74.5270844,28.9748388 C75.5296419,28.5348505 77.3711253,27.6215524 78.8849872,26.2797316 C80.9359335,24.4624511 83.1619693,19.6516023 83.5071355,19.4867859 C83.6485678,19.4190678 84.0818159,18.8873557 84.5433504,18.2839841 C84.4380818,20.1528593 84.1075959,23.4516963 83.8877494,24.3241486 C83.6969054,25.0815877 83.3796675,25.5523894 83.1841688,25.7877903 C82.9313811,30.4553204 82.6839642,34.4015994 82.5819182,34.6309093 C82.4494373,34.9297286 77.4857033,37.9225803 77.7019693,37.7939518" id="Fill-144" fill="#FFBC00"></path>
|
39 |
+
<path d="M69.0638619,21.8109128 C68.2421228,21.7654091 66.4196164,23.9409862 66.6924552,24.9556822 C67.0827366,25.1900082 69.2282097,25.7364106 69.9690281,25.7364106 C70.7102046,25.7364106 72.3092839,25.1423548 72.1921995,24.6196 C72.0751151,24.0968452 70.07,21.866807 69.0638619,21.8109128" id="Fill-146" fill="#98480C"></path>
|
40 |
+
<path d="M64.7448082,30.6150849 C64.6058824,31.069405 64.9764706,29.5201304 65.1325831,28.9748029 C65.2883376,28.4294755 67.8713555,27.6487471 69.9538107,27.6487471 C72.036266,27.6487471 73.3231202,26.9987971 73.7914578,28.0457398 C74.2594373,29.0926825 74.2984655,29.4832258 74.2984655,29.4832258 C74.2984655,29.4832258 73.442711,28.7806062 73.3829156,28.5853345 C73.3231202,28.3904211 72.9722251,28.8153609 70.4758568,29.0321304 C67.9798465,29.2488999 66.0295141,28.7763066 65.8343734,29.0321304 C65.6395908,29.2879542 64.864399,30.2248999 64.7448082,30.6150849" id="Fill-148" fill="#98480C"></path>
|
41 |
+
<path d="M69.5063836,31.2004341 C70.2028031,30.4981727 70.5533402,29.6393357 71.7431611,29.795553 C72.9333402,29.951412 73.7135448,31.9030537 73.0890946,31.7858907 C72.4653606,31.6687278 71.5598363,31.1613797 71.4080205,31.1613797 C71.2562046,31.1613797 69.5063836,31.2004341 69.5063836,31.2004341" id="Fill-150" fill="#98480C"></path>
|
42 |
+
<path d="M57.8664041,17.6369721 C57.6744859,17.2525198 63.2447673,17.2084493 63.8488082,17.2084493 C64.452491,17.2084493 66.2810844,16.8429868 66.3372992,17.4502996 C66.3935141,18.057254 64.961289,20.6258825 64.2179642,20.8125551 C63.4746394,20.9995859 59.2184246,20.3456946 57.8664041,17.6369721" id="Fill-152" fill="#1F191A"></path>
|
43 |
+
<path d="M80.294046,17.7116769 C80.4859642,17.3272247 75.1308747,17.0724758 74.5271918,17.0724758 C73.923509,17.0724758 71.8739949,16.8159354 71.8181381,17.4232482 C71.7619233,18.0302026 73.1937903,20.5988311 73.9374731,20.785862 C74.680798,20.9725345 78.9416675,20.4203994 80.294046,17.7116769" id="Fill-154" fill="#1F191A"></path>
|
44 |
+
<path d="M94.7082813,75.6808458 L100.201223,76.8281116 C100.313652,76.7091571 100.449355,76.5808869 100.613703,76.4418678 C106.021785,71.862837 111.178512,67.119348 111.178512,67.119348 L111.178512,70.2465609 C113.456465,67.263025 115.355954,64.1702085 116.904189,61.2568987 L113.182194,53.8505492 C113.182194,53.8505492 102.36424,53.9677122 100.094164,55.6234009 C97.824445,57.2787313 100.595801,60.469721 100.410685,62.0906549 C99.873243,66.7954479 98.0990742,68.495207 98.0990742,68.495207 C98.0990742,68.495207 99.141376,69.1168517 99.186133,71.0294391 C99.23089,72.9416681 97.5168747,73.5661791 94.7082813,75.6808458" id="Fill-156" fill="#98480C"></path>
|
45 |
+
<path d="M41.3225575,68.7320053 C40.1828645,67.469368 38.6013299,59.9103841 38.6013299,59.9103841 C38.3517647,55.955506 39.2884399,55.7545016 38.5798465,55.100252 C37.8712532,54.4456441 34.6555499,56.6817733 34.6555499,56.6817733 L28.4719182,69.2784076 L36.5099233,74.718067 L31.6095652,75.5826367 C31.6729412,75.6456969 31.735601,75.7094737 31.7996931,75.7721756 C32.8820972,76.6890567 33.7518159,77.2526573 34.4002558,77.6016382 C36.4322251,77.7782784 46.7392327,78.5643812 44.5751407,76.1523283 C42.1772379,73.4801521 41.0565217,70.5345956 41.3225575,68.7320053" id="Fill-158" fill="#98480C"></path>
|
46 |
+
<path d="M35.7649872,78.1532358 C35.7649872,78.1532358 40.873734,79.3065927 45.099156,79.6104282 C49.3249361,79.914622 55.3284655,73.2814767 69.0638619,73.2814767 L69.0638619,74.2209304 C69.0638619,74.2209304 58.0801279,76.5702814 48.5239642,81.1858584 C47.5575703,81.7383518 37.5058568,80.2886837 35.7649872,78.1532358" id="Fill-160" fill="#98480C"></path>
|
47 |
+
<path d="M39.5202097,79.7762479 C39.5202097,79.7762479 40.3763223,82.7332699 41.895555,83.1481774 C40.6248133,83.8113844 37.0517698,81.6279248 36.5096726,78.4494755 C39.503023,79.3061627 39.5202097,79.7762479 39.5202097,79.7762479" id="Fill-162" fill="#98480C"></path>
|
48 |
+
<path d="M66.0684706,45.7797028 C66.2947621,45.9380699 59.2184962,42.6288423 38.4469361,41.7442079 C35.2981893,41.9100993 37.1761944,40.6940405 39.2203376,40.1963665 C41.2644808,39.6986925 51.6499028,36.547832 52.9206445,35.884625 C54.1913862,35.2210596 55.9036113,34.9448129 54.578087,36.4926543 C53.2522046,38.0404957 45.6284706,40.4174355 44.523509,40.8043959 C43.4189054,41.1913562 61.0965013,42.2970596 66.0684706,45.7797028" id="Fill-164" fill="#98480C"></path>
|
49 |
+
<path d="M30.8233811,67.6705874 C36.5096726,68.1127254 57.8924348,69.0525374 67.1732532,66.399351 C64.5218465,68.0575477 60.2677801,69.3291424 50.0477801,69.3291424 C39.8277801,69.3291424 31.5412839,68.7762907 30.8233811,67.6705874" id="Fill-166" fill="#98480C"></path>
|
50 |
+
<path d="M102.362772,78.1532358 C102.362772,78.1532358 97.2540256,79.3065927 93.0286036,79.6104282 C88.8028235,79.914622 82.7992941,73.2814767 69.0638977,73.2814767 L69.0638977,74.2209304 C69.0638977,74.2209304 80.0476317,76.5702814 89.6037954,81.1858584 C90.5701893,81.7383518 100.621903,80.2886837 102.362772,78.1532358" id="Fill-168" fill="#98480C"></path>
|
51 |
+
<path d="M98.6075499,79.7762479 C98.6075499,79.7762479 97.7514373,82.7332699 96.2322046,83.1481774 C97.5029463,83.8113844 101.07599,81.6279248 101.618087,78.4494755 C98.6247366,79.3061627 98.6075499,79.7762479 98.6075499,79.7762479" id="Fill-170" fill="#98480C"></path>
|
52 |
+
<path d="M72.059289,45.7797028 C71.8329974,45.9380699 78.9092634,42.6288423 99.6808235,41.7442079 C102.829928,41.9100993 100.951565,40.6940405 98.907422,40.1963665 C96.8632788,39.6986925 86.4778568,36.547832 85.2071151,35.884625 C83.9363734,35.2210596 82.2241483,34.9448129 83.5496726,36.4926543 C84.875555,38.0404957 92.499289,40.4174355 93.6042506,40.8043959 C94.7088542,41.1913562 77.0312583,42.2970596 72.059289,45.7797028" id="Fill-172" fill="#98480C"></path>
|
53 |
+
<path d="M107.304414,67.6705874 C101.618123,68.1127254 80.2353606,69.0525374 70.9541841,66.399351 C73.6059488,68.0575477 77.8600153,69.3291424 88.0800153,69.3291424 C98.3000153,69.3291424 106.586153,68.7762907 107.304414,67.6705874" id="Fill-174" fill="#98480C"></path>
|
54 |
+
<path d="M69.2970997,45.2821363 C69.2970997,43.7894725 69.0640051,43.3473345 69.0640051,43.3473345 C69.0640051,43.3473345 68.8305524,43.7894725 68.8305524,45.2821363 C68.8305524,46.7748 68.1122916,62.6401744 68.0571509,63.3033815 C68.0020102,63.9669468 68.5788389,64.3539072 69.0640051,64.3539072 C69.5488133,64.3539072 70.1256419,63.9669468 70.0705013,63.3033815 C70.0153606,62.6401744 69.2970997,46.7748 69.2970997,45.2821363" id="Fill-176" fill="#98480C"></path>
|
55 |
+
<path d="M93.986046,104.143571 L69.0638977,104.143571 L44.1417494,104.143571 L42.3571969,111.286214 C55.8394476,115.253991 65.4145882,130.614526 65.4145882,130.614526 C65.4145882,130.614526 66.9416982,131.919442 69.0638977,131.919442 C71.1860972,131.919442 72.7132072,130.614526 72.7132072,130.614526 C72.7132072,130.614526 82.2883478,115.253991 95.7702404,111.286214 L93.986046,104.143571 Z" id="Fill-178" fill="#1F191A"></path>
|
56 |
+
<path d="M96.7585115,83.8684969 L95.9686394,84.5019653 C95.9686394,84.5019653 90.2730384,85.0311695 69.0639335,85.0311695 C47.8548286,85.0311695 42.1592276,84.5019653 42.1592276,84.5019653 L41.3693555,83.8684969 C41.3693555,83.8684969 40.0373862,84.4679272 40.4076164,86.8384176 C40.7015806,88.7241327 42.2261841,89.3593927 42.2261841,89.3593927 C42.2261841,89.3593927 42.8588696,98.5156628 42.7707877,99.2655777 C41.8455703,99.7062825 41.4048031,103.939199 44.1417852,104.143428 C52.4304297,104.480227 69.0639335,104.732826 69.0639335,104.732826 C69.0639335,104.732826 85.6970793,104.480227 93.9860818,104.143428 C96.7227059,103.939199 96.2822967,99.7062825 95.3567212,99.2655777 C95.2686394,98.5156628 95.9013248,89.3593927 95.9013248,89.3593927 C95.9013248,89.3593927 97.4259284,88.7241327 97.7202506,86.8384176 C98.0901228,84.4679272 96.7585115,83.8684969 96.7585115,83.8684969" id="Fill-180" fill="#FFBC00"></path>
|
57 |
+
<path d="M97.7202864,86.8382385 C98.0901586,84.4681063 96.7585473,83.8683178 96.7585473,83.8683178 L95.9686752,84.5017862 C95.9686752,84.5017862 90.2730742,85.0309903 69.0639693,85.0309903 C47.8548645,85.0309903 42.1592634,84.5017862 42.1592634,84.5017862 L41.3693913,83.8683178 C41.3693913,83.8683178 40.037422,84.4681063 40.4076522,86.8382385 C40.7016164,88.7239536 42.2262199,89.3595718 42.2262199,89.3595718 C42.2262199,89.3595718 42.4038159,91.9317833 42.5577801,94.4609991 C45.7312327,93.6591313 47.6615141,93.0145557 47.6615141,93.0145557 C47.6615141,93.0145557 53.1952737,93.8920241 54.7030486,93.7666203 C56.2111816,93.6412164 58.7168593,94.3932811 62.7260153,94.3932811 C66.7348133,94.3932811 68.5587519,92.3875366 68.5587519,92.3875366 C68.5587519,92.3875366 70.914046,92.2266614 70.9545064,90.8654925 C70.9759898,90.1331342 71.0651458,89.4874837 71.1761432,88.9102678 C71.0533299,90.2700035 71.8961944,89.7744793 72.5739949,90.3961239 C73.2528696,91.0188435 73.7000818,92.7748552 77.0260665,93.1779389 C80.3520512,93.5813809 83.7786496,91.7662502 85.0887775,91.6652106 C86.3989054,91.5645292 91.640133,92.1696922 92.696757,92.1696922 C92.9681637,92.1696922 94.0430486,92.4563295 95.6679079,92.8902267 C95.7903632,90.967607 95.9013606,89.3595718 95.9013606,89.3595718 C95.9013606,89.3595718 97.4259642,88.7239536 97.7202864,86.8382385" id="Fill-182" fill="#FF9000"></path>
|
58 |
+
<polygon id="Fill-184" fill="#98480C" points="70.36289 71.8627295 75.0011509 71.8627295 75.0011509 85.0161568 70.954399 85.0161568 70.0742967 78.0616194"></polygon>
|
59 |
+
<path d="M71.5167621,76.4331254 C71.5751253,74.6670814 69.7175294,74.374353 69.7483223,73.2815483 C69.7791151,72.1883853 71.3585013,72.839052 71.2346138,71.1969786 C71.1107263,69.5549051 68.8710844,67.5366203 67.1735396,67.8641034 C66.80689,67.4789345 66.6210588,66.1464294 66.2186036,65.7745175 C65.8161483,65.4029639 64.1440256,65.3409786 63.3079642,65.6817186 C62.4719028,66.0224587 62.1005985,66.6423119 60.7378363,66.983052 C59.3757903,67.3237921 58.7255601,67.2929786 57.9202916,68.3463706 C57.1153811,69.3997627 54.7930281,74.9770079 51.9446905,75.1317921 C49.0959949,75.2865762 48.2910844,75.1317921 42.841468,74.7290667 C37.3918517,74.3263413 32.716711,73.5689022 31.5089872,73.2815483 C30.3016215,72.9938361 29.3105217,72.4051548 29.3105217,72.4051548 C29.3105217,72.4051548 23.7735396,74.049378 19.9262251,79.3206379 C17.4305729,82.7402209 16.7538465,88.1261357 16.5855601,91.4901827 C11.0596777,90.9860593 8.00581586,89.5378244 6.5137954,88.647099 C8.57870588,89.8817891 13.6409054,92.1906526 24.138757,91.5664999 C36.7924655,90.8144352 47.6616215,87.1787994 47.6616215,87.1787994 C47.6616215,87.1787994 53.1953811,88.0562678 54.703156,87.930864 C56.211289,87.8054602 58.7169668,88.5578831 62.7257647,88.5578831 C66.7349207,88.5578831 68.5588593,86.5517803 68.5588593,86.5517803 C68.5588593,86.5517803 70.9141535,86.3909051 70.9542558,85.0297363 C70.9947161,83.6685674 71.2654066,82.5986937 71.4823887,81.7316159 C71.6990128,80.8638214 70.8321586,80.8018361 70.6151765,79.1285909 C70.3985524,77.455704 71.458399,78.1991695 71.5167621,76.4331254" id="Fill-192" fill="#FF5B0C"></path>
|
60 |
+
<path d="M18.2097391,67.119348 C18.2097391,67.119348 22.3531662,69.7255977 23.7144962,70.0810279 C25.0758261,70.4360999 29.3105575,72.4052981 29.3105575,72.4052981 C29.3105575,72.4052981 32.5617084,72.0025727 35.5342916,68.160558 C38.5068747,64.3185433 40.6741893,59.9806461 40.6741893,59.9806461 C40.6741893,59.9806461 40.9216061,61.3131512 41.7576675,63.0791953 C42.5937289,64.8452394 45.814087,67.8642467 45.814087,67.8642467 L48.4458005,51.4599941 L24.6125013,40.2589251 C24.6125013,40.2589251 15.0216061,40.4731865 11.3970026,53.8505492 C-0.254506394,61.8738855 3.60354987,65.5292276 2.24293606,69.1609222 C2.06140153,69.6446226 -0.416705882,78.6031131 0.460531969,83.2670602 C1.21209207,88.0564112 4.46932992,87.3039883 5.5968491,88.0564112 C4.99961125,67.1773921 18.2097391,67.119348 18.2097391,67.119348" id="Fill-196" fill="#9F5622"></path>
|
61 |
+
<path d="M19.9262609,79.3206737 C23.7735754,74.0494138 29.3105575,72.4051906 29.3105575,72.4051906 C29.3105575,72.4051906 25.0758261,70.4363507 23.7144962,70.0809204 C22.3531662,69.7254902 18.2097391,67.1192405 18.2097391,67.1192405 C18.2097391,67.1192405 4.99961125,67.1772846 5.5968491,88.0563037 C5.64053197,88.0853257 5.6910179,88.1193639 5.74544246,88.1562684 C5.76262916,88.1677339 5.78089003,88.179916 5.79879284,88.1920981 C5.82493095,88.2096546 5.85214322,88.2279278 5.88042967,88.2469175 C5.89833248,88.2587413 5.91766752,88.2712816 5.93628645,88.283822 C6.04119693,88.3529733 6.16042967,88.4303653 6.29577494,88.5145651 C6.30938107,88.5231642 6.32298721,88.531405 6.33730946,88.5400041 C6.38421483,88.5690261 6.43291049,88.5987648 6.48375448,88.62922 C6.49342199,88.635311 6.50380563,88.6414021 6.5138312,88.6471348 C8.00585166,89.5378602 11.0597136,90.9860952 16.5855959,91.4902185 C16.7538824,88.1261715 17.4306087,82.7402567 19.9262609,79.3206737" id="Fill-206" fill="#FFAD00"></path>
|
62 |
+
<path d="M120.61734,86.0000752 C120.437238,85.4146185 120.830384,82.7951119 120.109974,80.0928388 C118.219795,73.3371559 109.964092,71.469714 109.964092,71.469714 C108.012685,72.4600458 106.509207,72.8452147 104.303223,73.0150473 C102.097596,73.1845216 96.0457289,73.863852 91.973555,73.665714 C87.9013811,73.4675759 87.2507928,72.1092734 86.6571355,70.5248858 C86.0631202,68.9401398 84.5925831,66.5345363 83.5463427,65.9652029 C82.5001023,65.3958696 79.361023,64.1575965 78.2864962,63.3654026 C77.2119693,62.5728505 75.1474169,64.6670943 73.9880307,65.9652029 C72.9135038,65.6219548 71.3115601,66.4976317 70.4529412,67.864175 C69.5946803,69.2307184 71.5181586,71.1189416 71.5181586,71.1189416 C71.5181586,71.1189416 70.4529412,72.2224952 70.3684399,73.5524922 C70.2835806,74.8824893 71.6692583,75.2504599 71.7258312,76.12757 C71.7824041,77.0050385 70.6513043,77.4009562 70.5864962,78.701573 C70.522046,80.002548 71.8672634,80.3156993 71.838977,80.8581604 C71.8103325,81.4009797 71.3015345,81.7023072 71.1762148,83.0692088 C71.0508951,84.4361104 71.8955499,83.9380781 72.5740665,84.5604394 C73.2529412,85.1831589 73.7001535,86.9391706 77.0257801,87.3426126 C80.3517647,87.7460546 83.7787212,85.9305656 85.0888491,85.829526 C86.398977,85.7288446 91.6398465,86.3340076 92.6964706,86.3340076 C93.7534527,86.3340076 106.959284,90.6704717 117.541637,91.1749533 C118.268491,91.2097081 118.952737,91.2240399 119.604041,91.2236816 C120.32445,90.3411971 120.797442,86.5851736 120.61734,86.0000752" id="Fill-208" fill="#FF5B0C"></path>
|
63 |
+
<path d="M120.61734,86.0000752 C120.437238,85.4146185 120.830384,82.7951119 120.109974,80.0928388 C118.219795,73.3371559 109.964092,71.469714 109.964092,71.469714 C108.012685,72.4600458 106.509207,72.8452147 104.303223,73.0150473 C102.097596,73.1845216 96.0457289,73.863852 91.973555,73.665714 C87.9013811,73.4675759 87.2507928,72.1092734 86.6571355,70.5248858 C86.0631202,68.9401398 84.5925831,66.5345363 83.5463427,65.9652029 C82.5001023,65.3958696 79.361023,64.1575965 78.2864962,63.3654026 C77.2119693,62.5728505 75.1474169,64.6670943 73.9880307,65.9652029 C72.9135038,65.6219548 71.3115601,66.4976317 70.4529412,67.864175 C69.5946803,69.2307184 71.5181586,71.1189416 71.5181586,71.1189416 C71.5181586,71.1189416 70.4529412,72.2224952 70.3684399,73.5524922 C70.2835806,74.8824893 71.6692583,75.2504599 71.7258312,76.12757 C71.7824041,77.0050385 70.6513043,77.4009562 70.5864962,78.701573 C70.522046,80.002548 71.8672634,80.3156993 71.838977,80.8581604 C71.8103325,81.4009797 71.3015345,81.7023072 71.1762148,83.0692088 C71.0508951,84.4361104 71.8955499,83.9380781 72.5740665,84.5604394 C73.2529412,85.1831589 73.7001535,86.9391706 77.0257801,87.3426126 C80.3517647,87.7460546 83.7787212,85.9305656 85.0888491,85.829526 C86.398977,85.7288446 91.6398465,86.3340076 92.6964706,86.3340076 C93.7534527,86.3340076 106.959284,90.6704717 117.541637,91.1749533 C118.268491,91.2097081 118.952737,91.2240399 119.604041,91.2236816 C120.32445,90.3411971 120.797442,86.5851736 120.61734,86.0000752" id="Fill-210" fill="#FF5B0C"></path>
|
64 |
+
<g id="Group-222" stroke-width="1" fill="none" transform="translate(88.797954, 39.420869)">
|
65 |
+
<mask id="mask-6" fill="white">
|
66 |
+
<use xlink:href="#path-5"></use>
|
67 |
+
</mask>
|
68 |
+
<g id="Clip-221"></g>
|
69 |
+
<path d="M49.9089258,32.9952493 C48.1451407,26.1080717 47.9159847,22.6809645 46.842532,20.1868617 C44.3651407,14.4297515 37.9154731,12.160659 36.5043734,9.44584552 C33.7831458,2.68872952 26.765601,0.342961527 26.765601,0.342961527 C20.9217647,-1.75199883 0.178132992,17.6623037 0.331381074,17.7755254 C0.484987212,17.8887471 6.62565217,26.4061744 6.62565217,26.4061744 C6.62565217,26.4061744 8.32248082,24.5953433 9.11414322,22.4727941 C9.90616368,20.3506032 10.1270844,18.0868852 10.1270844,18.0868852 C10.1270844,18.0868852 10.1324552,17.945358 11.5177749,20.4355195 C12.9034527,22.9256811 16.952711,30.9454344 21.1659591,32.048988 C21.1659591,32.048988 24.7687212,30.7526708 24.9037084,30.7075254 C25.0386957,30.6627383 26.7938875,30.1220687 27.5314834,29.7168352 C28.2687212,29.3116018 31.8346036,27.4197956 31.8346036,27.4197956 C31.8346036,27.4197956 36.6157289,26.2273844 41.9167519,36.0672846 C44.8836061,41.574662 43.616087,47.3636605 43.1348593,49.0738103 C44.080844,48.7230379 45.016087,48.4432082 46.079156,48.3249703 C50.6146547,47.8204887 51.017468,44.39159 51.1184399,43.8462626 C51.2190537,43.3009351 50.2734271,34.4176869 49.9089258,32.9952493" id="Fill-220" fill="#9F5622" mask="url(#mask-6)"></path>
|
70 |
+
</g>
|
71 |
+
<path d="M130.714598,75.4880464 C125.413575,65.6481463 120.632808,66.8405574 120.632808,66.8405574 C120.632808,66.8405574 117.066926,68.7323636 116.32933,69.1375971 C115.592092,69.5428305 113.836542,70.0835001 113.701555,70.1286455 C113.566568,70.1734326 109.963806,71.4697498 109.963806,71.4697498 C109.963806,71.4697498 118.219867,73.3371918 120.110046,80.0928746 C120.830455,82.7951477 120.437309,85.4146543 120.617412,86.000111 C120.797514,86.5852094 120.324164,90.3412329 119.604113,91.2237175 C126.214189,91.2212094 129.120174,89.5393651 131.932706,88.4949304 C132.413934,86.7844223 133.681453,80.9954238 130.714598,75.4880464" id="Fill-223" fill="#FFAD00"></path>
|
72 |
+
<path d="M62.0177801,68.6410338 C61.1788542,68.6009046 61.4982404,69.1609222 61.4982404,69.1609222 C61.4982404,69.1609222 64.5349156,68.5210044 65.0941995,68.6808047 C65.5084706,68.7994009 66.930312,68.0688341 67.8462199,67.8491982 C67.6170639,67.8198179 67.3907724,67.822326 67.1734322,67.8642467 C67.1734322,67.8642467 62.8567059,68.6808047 62.0177801,68.6410338" id="Fill-225" fill="#E43500"></path>
|
73 |
+
<path d="M69.5144041,79.6354015 C70.5277033,79.9553604 70.9018721,80.1954191 70.9541483,80.2953838 C70.8130742,80.0137627 70.6827417,79.649375 70.6154271,79.12877 C70.398445,77.4558831 71.4582916,78.1993486 71.5166547,76.4329463 C71.5750179,74.6669022 70.3275499,74.3945968 70.3583427,73.3014338 C70.3894936,72.2082708 71.6419744,72.7611225 71.518087,71.119049 C71.4539949,70.2720358 70.5427417,69.4056746 69.7177801,68.7320769 C69.9938414,69.460494 70.5201841,71.0778449 70.074046,71.8392253 C69.4889821,72.8388728 69.4492379,73.0388023 69.5688286,73.4784323 C69.6887775,73.9180623 70.8979335,75.0294984 71.1668338,75.397469 C71.4360921,75.7657979 71.2423836,77.6937921 70.7253504,78.0449228 C70.2079591,78.3960535 68.5011049,79.3154426 69.5144041,79.6354015" id="Fill-227" fill="#E43500"></path>
|
74 |
+
<path d="M70.9543274,85.0296288 C70.9944297,83.6684599 71.2654783,82.5989445 71.4824604,81.7315084 C71.6317698,81.1338696 71.2669105,80.918175 70.9543274,80.2954555 C71.0066036,80.3954203 70.5676266,81.4344805 70.5676266,82.7537286 C70.5676266,84.0650943 71.0961176,85.0127888 70.6628696,85.7347565 C70.8322302,85.5452176 70.9460921,85.3151912 70.9543274,85.0296288" id="Fill-229" fill="#FF3500"></path>
|
75 |
+
<path d="M84.2314476,85.592262 C82.9130844,85.6721621 79.7167161,86.4718802 78.1985575,86.1519213 C76.680399,85.8319624 75.2023427,84.3127847 75.2023427,84.3127847 C75.2023427,84.3127847 73.0446957,84.2730138 72.8449003,84.1931137 C72.6451049,84.1132135 71.2698107,83.1135659 71.5183018,82.6338068 C71.7664348,82.1540476 72.4127263,81.7495307 72.1259233,81.3038097 C71.8387621,80.858447 71.6296573,79.7953809 71.5183018,79.2357216 C71.4065882,78.675704 71.6464859,78.1959448 71.7664348,77.5563853 C71.8860256,76.9168258 72.3257187,75.9573075 71.9261279,75.4374191 C71.5265371,74.917889 70.5279182,73.798212 70.5676624,73.3188112 C70.6077647,72.8386937 72.6053606,71.1998449 72.6053606,71.1998449 C72.6053606,71.1998449 71.1419847,70.0987994 70.2371765,68.7225821 C70.2873043,69.9071107 71.5183018,71.1188699 71.5183018,71.1188699 C71.5183018,71.1188699 70.4530844,72.2227818 70.3682251,73.5524206 C70.2833657,74.8824176 71.6694015,75.2503883 71.7256164,76.1274984 C71.7574834,76.6208728 71.4137494,76.9623295 71.0950793,77.3976599 C71.0027008,77.6964793 70.8788133,77.9404793 70.7255652,78.0447436 C70.6507315,78.2371489 70.5988133,78.4524852 70.5866394,78.7018596 C70.5221893,80.0024764 71.8670486,80.3156276 71.8387621,80.858447 C71.8104757,81.4009081 71.3016777,81.7025938 71.1763581,83.0691372 C71.0510384,84.4360388 71.895335,83.9380065 72.5742097,84.560726 C73.2527263,85.1830872 73.6999386,86.939099 77.0259233,87.342541 C80.3519079,87.745983 83.7785064,85.930494 85.0889923,85.8298126 C85.2007059,85.8212135 85.3428542,85.8179888 85.5064859,85.8187054 C85.2379437,85.6764617 84.8301176,85.556074 84.2314476,85.592262" id="Fill-231" fill="#E43500"></path>
|
76 |
+
<path d="M45.1709821,99.3815941 C46.4009054,99.526346 58.6414169,99.7434737 71.0423376,99.8158496 C83.4432583,99.8885838 93.7889361,99.5987219 93.7889361,99.5987219 C93.7889361,99.5987219 87.6393197,99.3815941 68.5395243,98.9473386 C49.4393708,98.5130831 45.1709821,99.3815941 45.1709821,99.3815941" id="Fill-233" fill="#F9D400"></path>
|
77 |
+
<path d="M44.4475294,89.2460634 C44.4475294,89.2460634 62.4208798,90.0425568 70.0743325,89.6803189 C77.7274271,89.3184394 93.4994476,89.2460634 93.4994476,89.2460634 C93.4994476,89.2460634 84.6303939,89.1736875 70.3629258,89.2460634 C56.0954578,89.3184394 44.4475294,89.2460634 44.4475294,89.2460634" id="Fill-235" fill="#FF7E00"></path>
|
78 |
+
<path d="M28.6531662,40.2588176 C26.7139335,40.2606091 26.462578,40.6927148 28.4719898,41.4390467 C30.4810435,42.1850203 35.3151611,47.8891025 40.4622199,48.6590819 C45.6092788,49.4294197 34.4056982,43.2129733 38.3457494,41.4630526 C44.1179744,38.8997985 32.8141381,41.1982714 32.2609412,41.0778837 C31.7077442,40.957496 29.5429361,40.258101 28.6531662,40.2588176" id="Fill-237" fill="#98480C"></path>
|
79 |
+
<path d="M100.438578,45.1806667 C101.692133,45.8399325 103.048092,44.966047 106.193616,42.8198502 C109.339499,40.6736535 111.877402,40.2085844 109.267887,39.4575947 C106.658373,38.7062467 105.292389,41.8047959 99.719601,40.4343113 C94.1471714,39.064185 95.2553555,40.3515448 95.2553555,40.3515448 C95.2553555,40.3515448 102.118578,42.3193098 101.153616,43.5353686 C100.188297,44.7514273 98.3292685,44.0717386 100.438578,45.1806667" id="Fill-239" fill="#98480C"></path>
|
80 |
+
</g>
|
81 |
+
</g>
|
82 |
+
</g>
|
83 |
+
</g>
|
84 |
+
</g>
|
85 |
+
</svg>
|
app/module/advanced-tools/img/spinner.svg
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<svg class="lds-spinner" width="28px" height="28px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" style="background: none;"><g transform="rotate(0 50 50)">
|
2 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
3 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.9166666666666666s" repeatCount="indefinite"></animate>
|
4 |
+
</rect>
|
5 |
+
</g><g transform="rotate(30 50 50)">
|
6 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
7 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.8333333333333334s" repeatCount="indefinite"></animate>
|
8 |
+
</rect>
|
9 |
+
</g><g transform="rotate(60 50 50)">
|
10 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
11 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.75s" repeatCount="indefinite"></animate>
|
12 |
+
</rect>
|
13 |
+
</g><g transform="rotate(90 50 50)">
|
14 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
15 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.6666666666666666s" repeatCount="indefinite"></animate>
|
16 |
+
</rect>
|
17 |
+
</g><g transform="rotate(120 50 50)">
|
18 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
19 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.5833333333333334s" repeatCount="indefinite"></animate>
|
20 |
+
</rect>
|
21 |
+
</g><g transform="rotate(150 50 50)">
|
22 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
23 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.5s" repeatCount="indefinite"></animate>
|
24 |
+
</rect>
|
25 |
+
</g><g transform="rotate(180 50 50)">
|
26 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
27 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.4166666666666667s" repeatCount="indefinite"></animate>
|
28 |
+
</rect>
|
29 |
+
</g><g transform="rotate(210 50 50)">
|
30 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
31 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.3333333333333333s" repeatCount="indefinite"></animate>
|
32 |
+
</rect>
|
33 |
+
</g><g transform="rotate(240 50 50)">
|
34 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
35 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.25s" repeatCount="indefinite"></animate>
|
36 |
+
</rect>
|
37 |
+
</g><g transform="rotate(270 50 50)">
|
38 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
39 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.16666666666666666s" repeatCount="indefinite"></animate>
|
40 |
+
</rect>
|
41 |
+
</g><g transform="rotate(300 50 50)">
|
42 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
43 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="-0.08333333333333333s" repeatCount="indefinite"></animate>
|
44 |
+
</rect>
|
45 |
+
</g><g transform="rotate(330 50 50)">
|
46 |
+
<rect x="47" y="24" rx="9.4" ry="4.8" width="6" height="12" fill="#1d0e0b">
|
47 |
+
<animate attributeName="opacity" values="1;0" times="0;1" dur="1s" begin="0s" repeatCount="indefinite"></animate>
|
48 |
+
</rect>
|
49 |
+
</g></svg>
|
app/module/advanced-tools/js/scripts.js
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
jQuery(function ($) {
|
2 |
+
Adtools.formHandler();
|
3 |
+
|
4 |
+
$('div.advanced-tools').on('form-submitted', function (e, data, form) {
|
5 |
+
if (form.attr('id') != 'advanced-settings-frm') {
|
6 |
+
return;
|
7 |
+
}
|
8 |
+
if (data.success == true) {
|
9 |
+
Defender.showNotification('success', data.data.message);
|
10 |
+
} else {
|
11 |
+
Defender.showNotification('error', data.data.message);
|
12 |
+
}
|
13 |
+
})
|
14 |
+
$('.deactivate-2factor').click(function () {
|
15 |
+
$('#advanced-settings-frm').append('<input type="hidden" name="enabled" value="0"/>');
|
16 |
+
$(this).attr('disabled', 'disabled');
|
17 |
+
$('#advanced-settings-frm').submit();
|
18 |
+
})
|
19 |
+
});
|
20 |
+
window.Adtools = window.Adtools || {};
|
21 |
+
Adtools.formHandler = function () {
|
22 |
+
var jq = jQuery;
|
23 |
+
jq('body').on('submit', '.advanced-settings-frm', function () {
|
24 |
+
var data = jq(this).serialize();
|
25 |
+
var that = jq(this);
|
26 |
+
jq.ajax({
|
27 |
+
type: 'POST',
|
28 |
+
url: ajaxurl,
|
29 |
+
data: data,
|
30 |
+
beforeSend: function () {
|
31 |
+
that.find('button[type="submit"]').attr('disabled', 'disabled');
|
32 |
+
},
|
33 |
+
success: function (data) {
|
34 |
+
if (data.data.reload != undefined) {
|
35 |
+
Defender.showNotification('success', data.data.message);
|
36 |
+
location.reload();
|
37 |
+
} else if (data.data != undefined && data.data.url != undefined) {
|
38 |
+
location.href = data.data.url;
|
39 |
+
} else {
|
40 |
+
that.find('button[type="submit"]').removeAttr('disabled');
|
41 |
+
jq('div.advanced-tools').trigger('form-submitted', [data, that])
|
42 |
+
}
|
43 |
+
}
|
44 |
+
})
|
45 |
+
return false;
|
46 |
+
})
|
47 |
+
}
|
app/module/advanced-tools/model/auth-settings.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Author: Hoang Ngo
|
5 |
+
*/
|
6 |
+
|
7 |
+
namespace WP_Defender\Module\Advanced_Tools\Model;
|
8 |
+
|
9 |
+
use Hammer\Helper\WP_Helper;
|
10 |
+
|
11 |
+
class Auth_Settings extends \Hammer\WP\Settings {
|
12 |
+
private static $_instance;
|
13 |
+
public $enabled = false;
|
14 |
+
public $lostPhone = true;
|
15 |
+
public $userRoles = array();
|
16 |
+
public $isConflict = array();
|
17 |
+
|
18 |
+
public function __construct( $id, $is_multi ) {
|
19 |
+
//fetch the userRoles
|
20 |
+
if ( ! function_exists( 'get_editable_roles' ) ) {
|
21 |
+
include_once ABSPATH . 'wp-admin/includes/user.php';
|
22 |
+
}
|
23 |
+
$this->userRoles = array_keys( get_editable_roles() );
|
24 |
+
//remove subscriber from the list
|
25 |
+
unset( $this->userRoles[ array_search( 'subscriber', $this->userRoles ) ] );
|
26 |
+
parent::__construct( $id, $is_multi );
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @return Auth_Settings
|
31 |
+
*/
|
32 |
+
public static function instance() {
|
33 |
+
if ( is_null( self::$_instance ) ) {
|
34 |
+
$class = new Auth_Settings( 'wd_2auth_settings', WP_Helper::is_network_activate( wp_defender()->plugin_slug ) );
|
35 |
+
self::$_instance = $class;
|
36 |
+
}
|
37 |
+
|
38 |
+
return self::$_instance;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param $plugin
|
43 |
+
*
|
44 |
+
* @return bool|int
|
45 |
+
*/
|
46 |
+
public function isConflict( $plugin ) {
|
47 |
+
if ( in_array( $plugin, $this->isConflict ) ) {
|
48 |
+
return true;
|
49 |
+
} elseif ( in_array( '!' . $plugin, $this->isConflict ) ) {
|
50 |
+
return false;
|
51 |
+
}
|
52 |
+
|
53 |
+
return 0;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @param $plugin
|
58 |
+
*/
|
59 |
+
public function markAsConflict( $plugin ) {
|
60 |
+
if ( ! in_array( $plugin, $this->isConflict ) ) {
|
61 |
+
$this->isConflict [] = $plugin;
|
62 |
+
$this->save();
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @param $plugin
|
68 |
+
*/
|
69 |
+
public function markAsUnConflict( $plugin ) {
|
70 |
+
if ( ( $i = array_search( $plugin, $this->isConflict ) ) !== false ) {
|
71 |
+
unset( $this->isConflict[ $i ] );
|
72 |
+
}
|
73 |
+
|
74 |
+
if ( ! in_array( '!' . $plugin, $this->isConflict ) ) {
|
75 |
+
$this->isConflict [] = '!' . $plugin;
|
76 |
+
$this->save();
|
77 |
+
}
|
78 |
+
}
|
79 |
+
|
80 |
+
public function events() {
|
81 |
+
$that = $this;
|
82 |
+
|
83 |
+
return array(
|
84 |
+
self::EVENT_AFTER_DELETED => array(
|
85 |
+
array(
|
86 |
+
function () use ( $that ) {
|
87 |
+
global $wpdb;
|
88 |
+
$sql = "DELETE from " . $wpdb->usermeta . " WHERE meta_key IN ('defOTPLoginToken','defenderBackupCode','defenderAuthSecret','defenderAuthOn','defenderAuthEmail')";
|
89 |
+
$wpdb->query( $sql );
|
90 |
+
}
|
91 |
+
)
|
92 |
+
)
|
93 |
+
);
|
94 |
+
}
|
95 |
+
}
|
app/module/advanced-tools/view/disabled.php
ADDED
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="dev-box">
|
2 |
+
<div class="box-title">
|
3 |
+
<h3 class="def-issues-title">
|
4 |
+
<?php _e( "2 Factor Authentication", wp_defender()->domain ) ?>
|
5 |
+
</h3>
|
6 |
+
</div>
|
7 |
+
<div class="box-content issues-box-content tc">
|
8 |
+
<img src="<?php echo wp_defender()->getPluginUrl() . 'assets/img/2factor-disabled.svg' ?>"/>
|
9 |
+
<p>
|
10 |
+
<?php _e( "Beef up your website’s security with 2-Step verification. Protect your user accounts by requiring a second passcode sent to users phones in order to get past your login screen - the best protection against brute force attacks.", wp_defender()->domain ) ?>
|
11 |
+
</p>
|
12 |
+
<form method="post" id="advanced-settings-frm" class="advanced-settings-frm">
|
13 |
+
|
14 |
+
<div class="clear line"></div>
|
15 |
+
<input type="hidden" name="action" value="saveAdvancedSettings"/>
|
16 |
+
<?php wp_nonce_field( 'saveAdvancedSettings' ) ?>
|
17 |
+
<input type="hidden" name="enabled" value="1"/>
|
18 |
+
<button type="submit" class="button button-primary">
|
19 |
+
<?php _e( "Activate", wp_defender()->domain ) ?>
|
20 |
+
</button>
|
21 |
+
<div class="clear"></div>
|
22 |
+
</form>
|
23 |
+
</div>
|
24 |
+
</div>
|
app/module/advanced-tools/view/layouts/layout.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
<div id="wp-defender" class="wp-defender">
|
3 |
+
<div class="advanced-tools">
|
4 |
+
<h2 class="title">
|
5 |
+
<?php _e( "Advanced Tools", wp_defender()->domain ) ?>
|
6 |
+
</h2>
|
7 |
+
<div class="row">
|
8 |
+
<div class="col-third">
|
9 |
+
<ul class="inner-nav is-hidden-mobile">
|
10 |
+
<li class="issues-nav">
|
11 |
+
<a class="<?php echo \Hammer\Helper\HTTP_Helper::retrieve_get( 'view', false ) == false ? 'active' : null ?>"
|
12 |
+
href="<?php echo network_admin_url( 'admin.php?page=wdf-advanced-tools' ) ?>">
|
13 |
+
<?php _e( "2 Factor Authentication", wp_defender()->domain ) ?>
|
14 |
+
</a>
|
15 |
+
</li>
|
16 |
+
</ul>
|
17 |
+
<div class="is-hidden-tablet mline">
|
18 |
+
<select class="mobile-nav">
|
19 |
+
<option <?php selected( '', \Hammer\Helper\HTTP_Helper::retrieve_get( 'view' ) ) ?>
|
20 |
+
value="<?php echo network_admin_url( 'admin.php?page=wdf-advanced-tools' ) ?>"><?php _e( "2 Factor Authentication", wp_defender()->domain ) ?></option>
|
21 |
+
</select>
|
22 |
+
</div>
|
23 |
+
</div>
|
24 |
+
<div class="col-two-third">
|
25 |
+
<?php echo $contents ?>
|
26 |
+
</div>
|
27 |
+
</div>
|
28 |
+
</div>
|
29 |
+
</div>
|
30 |
+
</div>
|
app/module/advanced-tools/view/login/disabled.php
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
<h2><?php _e( "Security", wp_defender()->domain ) ?></h2>
|
3 |
+
<table class="form-table">
|
4 |
+
<tbody>
|
5 |
+
<tr class="user-sessions-wrap hide-if-no-js">
|
6 |
+
<th><?php _e( "2 Factor Authentication", wp_defender()->domain ) ?></th>
|
7 |
+
<td aria-live="assertive">
|
8 |
+
<div id="def2">
|
9 |
+
<div class="destroy-sessions">
|
10 |
+
<button type="button" class="button" id="show2AuthActivator">
|
11 |
+
<?php _e( "Enable", wp_defender()->domain ) ?>
|
12 |
+
</button>
|
13 |
+
</div>
|
14 |
+
<p class="description">
|
15 |
+
<?php _e( "Use the Google Authenticator app to sign in with a separate passcode.", wp_defender()->domain ) ?>
|
16 |
+
</p>
|
17 |
+
</div>
|
18 |
+
<div id="def2qr">
|
19 |
+
<button type="button" id="hide2AuthActivator"
|
20 |
+
class="button"><?php _e( "Cancel", wp_defender()->domain ) ?></button>
|
21 |
+
<p><?php _e( "Use the Google Authenticator app to sign in with a separate passcode.", wp_defender()->domain ) ?></p>
|
22 |
+
<div class="card">
|
23 |
+
<p>
|
24 |
+
<strong><?php _e( "1. Install the Verification app", wp_defender()->domain ) ?></strong>
|
25 |
+
</p>
|
26 |
+
<p>
|
27 |
+
<?php _e( "Download and install the Google Authenticator app on your device using the links below.", wp_defender()->domain ) ?>
|
28 |
+
</p>
|
29 |
+
<a href="https://itunes.apple.com/vn/app/google-authenticator/id388497605?mt=8">
|
30 |
+
<img src="<?php echo wp_defender()->getPluginUrl() . 'assets/img/ios-download.svg' ?>"/>
|
31 |
+
</a>
|
32 |
+
<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">
|
33 |
+
<img src="<?php echo wp_defender()->getPluginUrl() . 'assets/img/android-download.svg' ?>"/>
|
34 |
+
</a>
|
35 |
+
<div class="line"></div>
|
36 |
+
<p><strong><?php _e( "2. Scan the barcode", wp_defender()->domain ) ?></strong></p>
|
37 |
+
<p><?php _e( "Open the Google Authenticator app you just downloaded, tap the “+” symbol and then use your phone’s camera to scan the barcode below.", wp_defender()->domain ) ?></p>
|
38 |
+
<img class="barcode"
|
39 |
+
src="<?php echo \WP_Defender\Module\Advanced_Tools\Component\Auth_API::generateQRCode( get_site_url(), $secretKey, 149, 149, 'wp-defender' ) ?>"/>
|
40 |
+
<div class="line"></div>
|
41 |
+
<p><strong><?php _e( "3. Enter passcode", wp_defender()->domain ) ?></strong></p>
|
42 |
+
<p>
|
43 |
+
<?php _e( "Enter the 6 digit passcode that is shown on your device into the input field below and hit “Verify”.", wp_defender()->domain ) ?>
|
44 |
+
</p>
|
45 |
+
<div class="well">
|
46 |
+
<p class="error"></p>
|
47 |
+
<input type="text" id="otpCode" class="def-small-text">
|
48 |
+
<button type="button" class="button button-primary" id="verifyOTP">
|
49 |
+
<?php _e( "Verify", wp_defender()->domain ) ?>
|
50 |
+
</button>
|
51 |
+
<input type="hidden" id="defNonce" value="<?php echo wp_create_nonce( 'defVerifyOTP' ) ?>"/>
|
52 |
+
</div>
|
53 |
+
</div>
|
54 |
+
</div>
|
55 |
+
</td>
|
56 |
+
</tr>
|
57 |
+
</tbody>
|
58 |
+
</table>
|
59 |
+
</div>
|
60 |
+
<script type="text/javascript">
|
61 |
+
jQuery(function ($) {
|
62 |
+
$('#def2qr').hide();
|
63 |
+
$('#show2AuthActivator').click(function () {
|
64 |
+
$('#def2').hide();
|
65 |
+
$('#def2qr').show();
|
66 |
+
});
|
67 |
+
$('#hide2AuthActivator').click(function () {
|
68 |
+
$('#def2qr').hide();
|
69 |
+
$('#def2').show();
|
70 |
+
})
|
71 |
+
$('#verifyOTP').click(function () {
|
72 |
+
var data = {
|
73 |
+
action: 'defVerifyOTP',
|
74 |
+
otp: $('#otpCode').val(),
|
75 |
+
nonce: $('#defNonce').val()
|
76 |
+
}
|
77 |
+
var that = $(this);
|
78 |
+
var parent = that.closest('.well');
|
79 |
+
$.ajax({
|
80 |
+
type: 'POST',
|
81 |
+
url: ajaxurl,
|
82 |
+
data: data,
|
83 |
+
beforeSend: function () {
|
84 |
+
that.attr('disabled', 'disabled');
|
85 |
+
},
|
86 |
+
success: function (data) {
|
87 |
+
if (data.success == true) {
|
88 |
+
location.reload();
|
89 |
+
} else {
|
90 |
+
that.removeAttr('disabled');
|
91 |
+
parent.find('.error').text(data.data.message);
|
92 |
+
}
|
93 |
+
}
|
94 |
+
})
|
95 |
+
})
|
96 |
+
})
|
97 |
+
</script>
|
app/module/advanced-tools/view/login/enabled.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
<h2><?php _e( "Security", wp_defender()->domain ) ?></h2>
|
3 |
+
<table class="form-table">
|
4 |
+
<tbody>
|
5 |
+
<tr class="user-sessions-wrap hide-if-no-js">
|
6 |
+
<th><?php _e( "2 Factor Authentication", wp_defender()->domain ) ?></th>
|
7 |
+
<td aria-live="assertive">
|
8 |
+
<div class="def-notification">
|
9 |
+
<?php _e( "2 factor authentication is active.", wp_defender()->domain ) ?>
|
10 |
+
</div>
|
11 |
+
<button type="button" class="button" id="disableOTP">
|
12 |
+
<?php _e( "Disabled", wp_defender()->domain ) ?>
|
13 |
+
</button>
|
14 |
+
</td>
|
15 |
+
</tr>
|
16 |
+
<tr class="user-sessions-wrap hide-if-no-js">
|
17 |
+
<th><?php _e( "Fallback email address", wp_defender()->domain ) ?></th>
|
18 |
+
<td aria-live="assertive">
|
19 |
+
<input type="text" class="regular-text" name="def_backup_email" value="<?php echo $email ?>"/>
|
20 |
+
<p class="description">
|
21 |
+
<?php _e( "If you ever lose your device, you can send a fallback passcode to this email address.", wp_defender()->domain ) ?>
|
22 |
+
</p>
|
23 |
+
</td>
|
24 |
+
</tr>
|
25 |
+
</tbody>
|
26 |
+
</table>
|
27 |
+
</div>
|
28 |
+
<script type="text/javascript">
|
29 |
+
jQuery(function ($) {
|
30 |
+
$('#disableOTP').click(function () {
|
31 |
+
var data = {
|
32 |
+
action: 'defDisableOTP'
|
33 |
+
}
|
34 |
+
var that = $(this);
|
35 |
+
$.ajax({
|
36 |
+
type: 'POST',
|
37 |
+
url: ajaxurl,
|
38 |
+
data: data,
|
39 |
+
beforeSend: function () {
|
40 |
+
that.attr('disabled', 'disabled');
|
41 |
+
},
|
42 |
+
success: function (data) {
|
43 |
+
if (data.success == true) {
|
44 |
+
location.reload();
|
45 |
+
} else {
|
46 |
+
that.removeAttr('disabled');
|
47 |
+
}
|
48 |
+
}
|
49 |
+
})
|
50 |
+
})
|
51 |
+
})
|
52 |
+
</script>
|
app/module/advanced-tools/view/login/otp.php
ADDED
@@ -0,0 +1,316 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! function_exists( 'login_header' ) ) {
|
3 |
+
//copy from wp-login
|
4 |
+
/**
|
5 |
+
* Output the login page header.
|
6 |
+
*
|
7 |
+
* @param string $title Optional. WordPress login Page title to display in the `<title>` element.
|
8 |
+
* Default 'Log In'.
|
9 |
+
* @param string $message Optional. Message to display in header. Default empty.
|
10 |
+
* @param WP_Error $wp_error Optional. The error to pass. Default empty.
|
11 |
+
*/
|
12 |
+
function login_header( $title = 'Log In', $message = '', $wp_error = '' ) {
|
13 |
+
global $error, $interim_login, $action;
|
14 |
+
|
15 |
+
if ( empty( $wp_error ) ) {
|
16 |
+
$wp_error = new WP_Error();
|
17 |
+
}
|
18 |
+
|
19 |
+
// Shake it!
|
20 |
+
$shake_error_codes = array(
|
21 |
+
'empty_password',
|
22 |
+
'empty_email',
|
23 |
+
'invalid_email',
|
24 |
+
'invalidcombo',
|
25 |
+
'empty_username',
|
26 |
+
'invalid_username',
|
27 |
+
'incorrect_password'
|
28 |
+
);
|
29 |
+
/**
|
30 |
+
* Filters the error codes array for shaking the login form.
|
31 |
+
*
|
32 |
+
* @since 3.0.0
|
33 |
+
*
|
34 |
+
* @param array $shake_error_codes Error codes that shake the login form.
|
35 |
+
*/
|
36 |
+
$shake_error_codes = apply_filters( 'shake_error_codes', $shake_error_codes );
|
37 |
+
|
38 |
+
if ( $shake_error_codes && $wp_error->get_error_code() && in_array( $wp_error->get_error_code(), $shake_error_codes ) ) {
|
39 |
+
add_action( 'login_head', 'wp_shake_js', 12 );
|
40 |
+
}
|
41 |
+
|
42 |
+
$separator = is_rtl() ? ' › ' : ' ‹ ';
|
43 |
+
|
44 |
+
?><!DOCTYPE html>
|
45 |
+
<!--[if IE 8]>
|
46 |
+
<html xmlns="http://www.w3.org/1999/xhtml" class="ie8" <?php language_attributes(); ?>>
|
47 |
+
<![endif]-->
|
48 |
+
<!--[if !(IE 8) ]><!-->
|
49 |
+
<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
|
50 |
+
<!--<![endif]-->
|
51 |
+
<head>
|
52 |
+
<meta http-equiv="Content-Type"
|
53 |
+
content="<?php bloginfo( 'html_type' ); ?>; charset=<?php bloginfo( 'charset' ); ?>"/>
|
54 |
+
<title><?php echo get_bloginfo( 'name', 'display' ) . $separator . $title; ?></title>
|
55 |
+
<?php
|
56 |
+
|
57 |
+
wp_enqueue_style( 'login' );
|
58 |
+
|
59 |
+
/*
|
60 |
+
* Remove all stored post data on logging out.
|
61 |
+
* This could be added by add_action('login_head'...) like wp_shake_js(),
|
62 |
+
* but maybe better if it's not removable by plugins
|
63 |
+
*/
|
64 |
+
if ( 'loggedout' == $wp_error->get_error_code() ) {
|
65 |
+
?>
|
66 |
+
<script>if ("sessionStorage" in window) {
|
67 |
+
try {
|
68 |
+
for (var key in sessionStorage) {
|
69 |
+
if (key.indexOf("wp-autosave-") != -1) {
|
70 |
+
sessionStorage.removeItem(key)
|
71 |
+
}
|
72 |
+
}
|
73 |
+
} catch (e) {
|
74 |
+
}
|
75 |
+
}
|
76 |
+
;</script>
|
77 |
+
<?php
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Enqueue scripts and styles for the login page.
|
82 |
+
*
|
83 |
+
* @since 3.1.0
|
84 |
+
*/
|
85 |
+
do_action( 'login_enqueue_scripts' );
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Fires in the login page header after scripts are enqueued.
|
89 |
+
*
|
90 |
+
* @since 2.1.0
|
91 |
+
*/
|
92 |
+
do_action( 'login_head' );
|
93 |
+
|
94 |
+
if ( is_multisite() ) {
|
95 |
+
$login_header_url = network_home_url();
|
96 |
+
$login_header_title = get_network()->site_name;
|
97 |
+
} else {
|
98 |
+
$login_header_url = __( 'https://wordpress.org/' );
|
99 |
+
$login_header_title = __( 'Powered by WordPress' );
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Filters link URL of the header logo above login form.
|
104 |
+
*
|
105 |
+
* @since 2.1.0
|
106 |
+
*
|
107 |
+
* @param string $login_header_url Login header logo URL.
|
108 |
+
*/
|
109 |
+
$login_header_url = apply_filters( 'login_headerurl', $login_header_url );
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Filters the title attribute of the header logo above login form.
|
113 |
+
*
|
114 |
+
* @since 2.1.0
|
115 |
+
*
|
116 |
+
* @param string $login_header_title Login header logo title attribute.
|
117 |
+
*/
|
118 |
+
$login_header_title = apply_filters( 'login_headertitle', $login_header_title );
|
119 |
+
|
120 |
+
$classes = array( 'login-action-' . $action, 'wp-core-ui' );
|
121 |
+
if ( is_rtl() ) {
|
122 |
+
$classes[] = 'rtl';
|
123 |
+
}
|
124 |
+
if ( $interim_login ) {
|
125 |
+
$classes[] = 'interim-login';
|
126 |
+
?>
|
127 |
+
<style type="text/css">html {
|
128 |
+
background-color: transparent;
|
129 |
+
}</style>
|
130 |
+
<?php
|
131 |
+
|
132 |
+
if ( 'success' === $interim_login ) {
|
133 |
+
$classes[] = 'interim-login-success';
|
134 |
+
}
|
135 |
+
}
|
136 |
+
$classes[] = ' locale-' . sanitize_html_class( strtolower( str_replace( '_', '-', get_locale() ) ) );
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Filters the login page body classes.
|
140 |
+
*
|
141 |
+
* @since 3.5.0
|
142 |
+
*
|
143 |
+
* @param array $classes An array of body classes.
|
144 |
+
* @param string $action The action that brought the visitor to the login page.
|
145 |
+
*/
|
146 |
+
$classes = apply_filters( 'login_body_class', $classes, $action );
|
147 |
+
|
148 |
+
?>
|
149 |
+
</head>
|
150 |
+
<body class="login <?php echo esc_attr( implode( ' ', $classes ) ); ?>">
|
151 |
+
<?php
|
152 |
+
/**
|
153 |
+
* Fires in the login page header after the body tag is opened.
|
154 |
+
*
|
155 |
+
* @since 4.6.0
|
156 |
+
*/
|
157 |
+
do_action( 'login_header' );
|
158 |
+
?>
|
159 |
+
<div id="login">
|
160 |
+
<h1><a href="<?php echo esc_url( $login_header_url ); ?>" title="<?php echo esc_attr( $login_header_title ); ?>"
|
161 |
+
tabindex="-1"><?php bloginfo( 'name' ); ?></a></h1>
|
162 |
+
<?php
|
163 |
+
|
164 |
+
unset( $login_header_url, $login_header_title );
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Filters the message to display above the login form.
|
168 |
+
*
|
169 |
+
* @since 2.1.0
|
170 |
+
*
|
171 |
+
* @param string $message Login message text.
|
172 |
+
*/
|
173 |
+
$message = apply_filters( 'login_message', $message );
|
174 |
+
if ( ! empty( $message ) ) {
|
175 |
+
echo $message . "\n";
|
176 |
+
}
|
177 |
+
|
178 |
+
// In case a plugin uses $error rather than the $wp_errors object
|
179 |
+
if ( ! empty( $error ) ) {
|
180 |
+
$wp_error->add( 'error', $error );
|
181 |
+
unset( $error );
|
182 |
+
}
|
183 |
+
|
184 |
+
if ( $wp_error->get_error_code() ) {
|
185 |
+
$errors = '';
|
186 |
+
$messages = '';
|
187 |
+
foreach ( $wp_error->get_error_codes() as $code ) {
|
188 |
+
$severity = $wp_error->get_error_data( $code );
|
189 |
+
foreach ( $wp_error->get_error_messages( $code ) as $error_message ) {
|
190 |
+
if ( 'message' == $severity ) {
|
191 |
+
$messages .= ' ' . $error_message . "<br />\n";
|
192 |
+
} else {
|
193 |
+
$errors .= ' ' . $error_message . "<br />\n";
|
194 |
+
}
|
195 |
+
}
|
196 |
+
}
|
197 |
+
if ( ! empty( $errors ) ) {
|
198 |
+
/**
|
199 |
+
* Filters the error messages displayed above the login form.
|
200 |
+
*
|
201 |
+
* @since 2.1.0
|
202 |
+
*
|
203 |
+
* @param string $errors Login error message.
|
204 |
+
*/
|
205 |
+
echo '<div id="login_error">' . apply_filters( 'login_errors', $errors ) . "</div>\n";
|
206 |
+
}
|
207 |
+
if ( ! empty( $messages ) ) {
|
208 |
+
/**
|
209 |
+
* Filters instructional messages displayed above the login form.
|
210 |
+
*
|
211 |
+
* @since 2.5.0
|
212 |
+
*
|
213 |
+
* @param string $messages Login messages.
|
214 |
+
*/
|
215 |
+
echo '<p class="message">' . apply_filters( 'login_messages', $messages ) . "</p>\n";
|
216 |
+
}
|
217 |
+
}
|
218 |
+
}
|
219 |
+
}
|
220 |
+
login_header( '', '', $error );
|
221 |
+
?>
|
222 |
+
<form method="post"
|
223 |
+
action="<?php echo esc_url( add_query_arg( 'action', 'defenderVerifyOTP', site_url( 'wp-login.php', 'login_post' ) ) ); ?>">
|
224 |
+
<p><?php _e( "Enter 6 digit passcode", wp_defender()->domain ) ?></p>
|
225 |
+
<input type="text" value="" name="otp">
|
226 |
+
<button class="button button-primary float-r"
|
227 |
+
type="submit"><?php _e( "Authenticate", wp_defender()->domain ) ?></button>
|
228 |
+
<input type="hidden" name="login_token" value="<?php echo $loginToken ?>"/>
|
229 |
+
<input type="hidden" name="redirect_to" value="<?php echo $redirect_to ?>"/>
|
230 |
+
<?php wp_nonce_field( 'DefOtpCheck' ) ?>
|
231 |
+
</form>
|
232 |
+
<?php if ( \WP_Defender\Module\Advanced_Tools\Model\Auth_Settings::instance()->lostPhone ): ?>
|
233 |
+
<p id="nav">
|
234 |
+
<a id="lostPhone"
|
235 |
+
href="<?php echo admin_url( 'admin-ajax.php?action=defRetrieveOTP&token=' . $loginToken . '&nonce=' . wp_create_nonce( 'defRetrieveOTP' ) ) ?>">
|
236 |
+
<?php _e( "Lost your device?", wp_defender()->domain ) ?></a>
|
237 |
+
<img class="def-ajaxloader" src="<?php echo wp_defender()->getPluginUrl().'app/module/advanced-tools/img/spinner.svg' ?>"/>
|
238 |
+
<strong class="notification">
|
239 |
+
|
240 |
+
</strong>
|
241 |
+
</p>
|
242 |
+
<script type="text/javascript">
|
243 |
+
jQuery(function ($) {
|
244 |
+
$('.def-ajaxloader').hide();
|
245 |
+
var isSent = false;
|
246 |
+
$('#lostPhone').click(function (e) {
|
247 |
+
e.preventDefault();
|
248 |
+
var that = $(this);
|
249 |
+
if (isSent == false) {
|
250 |
+
isSent = true;
|
251 |
+
$.ajax({
|
252 |
+
type: 'GET',
|
253 |
+
url: that.attr('href'),
|
254 |
+
beforeSend: function () {
|
255 |
+
that.attr('disabled', 'disabled');
|
256 |
+
$('.def-ajaxloader').show();
|
257 |
+
},
|
258 |
+
success: function (data) {
|
259 |
+
that.removeAttr('disabled');
|
260 |
+
$('.def-ajaxloader').hide();
|
261 |
+
$('.notification').text(data.data.message);
|
262 |
+
isSent = false;
|
263 |
+
}
|
264 |
+
})
|
265 |
+
}
|
266 |
+
|
267 |
+
})
|
268 |
+
})
|
269 |
+
</script>
|
270 |
+
<?php endif; ?>
|
271 |
+
<?php
|
272 |
+
if ( ! function_exists( 'login_footer' ) ) {
|
273 |
+
//copy from wp login
|
274 |
+
/**
|
275 |
+
* Outputs the footer for the login page.
|
276 |
+
*
|
277 |
+
* @param string $input_id Which input to auto-focus
|
278 |
+
*/
|
279 |
+
function login_footer( $input_id = '' ) {
|
280 |
+
global $interim_login;
|
281 |
+
|
282 |
+
// Don't allow interim logins to navigate away from the page.
|
283 |
+
if ( ! $interim_login ): ?>
|
284 |
+
<p id="backtoblog"><a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php
|
285 |
+
/* translators: %s: site title */
|
286 |
+
printf( _x( '← Back to %s', 'site' ), get_bloginfo( 'title', 'display' ) );
|
287 |
+
?></a></p>
|
288 |
+
<?php endif; ?>
|
289 |
+
|
290 |
+
</div>
|
291 |
+
|
292 |
+
<?php if ( ! empty( $input_id ) ) : ?>
|
293 |
+
<script type="text/javascript">
|
294 |
+
try {
|
295 |
+
document.getElementById('<?php echo $input_id; ?>').focus();
|
296 |
+
} catch (e) {
|
297 |
+
}
|
298 |
+
if (typeof wpOnload == 'function') wpOnload();
|
299 |
+
</script>
|
300 |
+
<?php endif; ?>
|
301 |
+
|
302 |
+
<?php
|
303 |
+
/**
|
304 |
+
* Fires in the login page footer.
|
305 |
+
*
|
306 |
+
* @since 3.1.0
|
307 |
+
*/
|
308 |
+
do_action( 'login_footer' ); ?>
|
309 |
+
<div class="clear"></div>
|
310 |
+
</body>
|
311 |
+
</html>
|
312 |
+
<?php
|
313 |
+
}
|
314 |
+
}
|
315 |
+
login_footer();
|
316 |
+
?>
|
app/module/advanced-tools/view/main.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="dev-box">
|
2 |
+
<div class="box-title">
|
3 |
+
<h3 class="def-issues-title">
|
4 |
+
<?php _e( "2 Factor Authentication", wp_defender()->domain ) ?>
|
5 |
+
</h3>
|
6 |
+
</div>
|
7 |
+
<div class="box-content issues-box-content">
|
8 |
+
<form method="post" id="advanced-settings-frm" class="advanced-settings-frm">
|
9 |
+
<p class="<?php echo isset( wp_defender()->global['compatibility'] ) ? 'line' : null ?>"><?php _e( "Configure your 2 factor authentication settings, our recommendations are on by default.", wp_defender()->domain ) ?></p>
|
10 |
+
<?php if ( isset( wp_defender()->global['compatibility'] ) ): ?>
|
11 |
+
<div class="well well-error with-cap">
|
12 |
+
<i class="def-icon icon-warning icon-yellow "></i>
|
13 |
+
<?php echo implode( '<br/>', wp_defender()->global['compatibility'] ); ?>
|
14 |
+
</div>
|
15 |
+
<?php endif; ?>
|
16 |
+
<div class="columns">
|
17 |
+
<div class="column is-one-third">
|
18 |
+
<label><?php _e( "User Roles", wp_defender()->domain ) ?></label>
|
19 |
+
<span class="sub">
|
20 |
+
<?php _e( "Choose what user roles you want to enable 2 factor authentication for. They must then use the Google Authenticator app to login.", wp_defender()->domain ) ?>
|
21 |
+
</span>
|
22 |
+
</div>
|
23 |
+
<div class="column">
|
24 |
+
<ul class="dev-list marginless">
|
25 |
+
<li class="list-header">
|
26 |
+
<div>
|
27 |
+
<span class="list-label"><?php _e( "User role", wp_defender()->domain ) ?></span>
|
28 |
+
</div>
|
29 |
+
</li>
|
30 |
+
<?php
|
31 |
+
$enabledRoles = $settings->userRoles;
|
32 |
+
$allRoles = get_editable_roles();
|
33 |
+
foreach ( $allRoles as $role => $detail ):
|
34 |
+
?>
|
35 |
+
<li>
|
36 |
+
<div>
|
37 |
+
<span class="list-label">
|
38 |
+
<?php echo $detail['name'] ?>
|
39 |
+
</span>
|
40 |
+
<div class="list-detail">
|
41 |
+
<span class="toggle">
|
42 |
+
<input type="checkbox" <?php echo in_array( $role, $enabledRoles ) ? 'checked="checked"' : null ?>
|
43 |
+
name="userRoles[]"
|
44 |
+
value="<?php echo esc_attr( $role ) ?>"
|
45 |
+
class="toggle-checkbox"
|
46 |
+
id="toggle_<?php echo esc_attr( $role ) ?>_role"/>
|
47 |
+
<label class="toggle-label"
|
48 |
+
for="toggle_<?php echo esc_attr( $role ) ?>_role"></label>
|
49 |
+
</span>
|
50 |
+
</div>
|
51 |
+
</div>
|
52 |
+
</li>
|
53 |
+
<?php endforeach; ?>
|
54 |
+
</ul>
|
55 |
+
</div>
|
56 |
+
</div>
|
57 |
+
<div class="columns">
|
58 |
+
<div class="column is-one-third">
|
59 |
+
<label><?php _e( "Lost Phone", wp_defender()->domain ) ?></label>
|
60 |
+
<span class="sub">
|
61 |
+
<?php _e( "If a user is unable to access their phone, you can allow an option to send the one time password to their registered email.", wp_defender()->domain ) ?>
|
62 |
+
</span>
|
63 |
+
</div>
|
64 |
+
<div class="column">
|
65 |
+
<span class="toggle">
|
66 |
+
<input type="hidden" name="lostPhone" value="0"/>
|
67 |
+
<input type="checkbox" checked="checked" name="lostPhone" value="1"
|
68 |
+
class="toggle-checkbox" id="toggle_lost_phone"/>
|
69 |
+
<label class="toggle-label" for="toggle_lost_phone"></label>
|
70 |
+
</span>
|
71 |
+
<span><?php _e( "Enable lost phone option", wp_defender()->domain ) ?></span>
|
72 |
+
</div>
|
73 |
+
</div>
|
74 |
+
<div class="columns">
|
75 |
+
<div class="column is-one-third">
|
76 |
+
<label><?php _e( "App Download", wp_defender()->domain ) ?></label>
|
77 |
+
<span class="sub">
|
78 |
+
<?php _e( "Need the app? Here’s links to the official Google Authenticator apps.", wp_defender()->domain ) ?>
|
79 |
+
</span>
|
80 |
+
</div>
|
81 |
+
<div class="column">
|
82 |
+
<a href="https://itunes.apple.com/vn/app/google-authenticator/id388497605?mt=8">
|
83 |
+
<img src="<?php echo wp_defender()->getPluginUrl() . 'assets/img/ios-download.svg' ?>"/>
|
84 |
+
</a>
|
85 |
+
<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2">
|
86 |
+
<img src="<?php echo wp_defender()->getPluginUrl() . 'assets/img/android-download.svg' ?>"/>
|
87 |
+
</a>
|
88 |
+
</div>
|
89 |
+
</div>
|
90 |
+
<div class="columns">
|
91 |
+
<div class="column is-one-third">
|
92 |
+
<label><?php _e( "Active Users", wp_defender()->domain ) ?></label>
|
93 |
+
<span class="sub">
|
94 |
+
<?php _e( "Here’s a quick link to see which of your users have enabled 2 step verification.", wp_defender()->domain ) ?>
|
95 |
+
</span>
|
96 |
+
</div>
|
97 |
+
<div class="column">
|
98 |
+
<?php printf( __( "<a href=\"%s\">View users</a> who have enabled this feature.", wp_defender()->domain ), network_admin_url( 'users.php' ) ) ?>
|
99 |
+
</div>
|
100 |
+
</div>
|
101 |
+
<div class="columns mline">
|
102 |
+
<div class="column is-one-third">
|
103 |
+
<label><?php _e( "Deactivate", wp_defender()->domain ) ?></label>
|
104 |
+
<span class="sub">
|
105 |
+
<?php _e( "Turn off the 2 factor authentication feature completely.", wp_defender()->domain ) ?>
|
106 |
+
</span>
|
107 |
+
</div>
|
108 |
+
<div class="column">
|
109 |
+
<button type="button" class="button button-secondary deactivate-2factor">
|
110 |
+
<?php _e( "Deactivate", wp_defender()->domain ) ?>
|
111 |
+
</button>
|
112 |
+
</div>
|
113 |
+
</div>
|
114 |
+
<div class="clear line"></div>
|
115 |
+
<input type="hidden" name="action" value="saveAdvancedSettings"/>
|
116 |
+
<?php wp_nonce_field( 'saveAdvancedSettings' ) ?>
|
117 |
+
<button type="submit" class="button button-primary float-r">
|
118 |
+
<?php _e( "SAVE SETTINGS", wp_defender()->domain ) ?>
|
119 |
+
</button>
|
120 |
+
<div class="clear"></div>
|
121 |
+
</form>
|
122 |
+
</div>
|
123 |
+
</div>
|
app/module/audit/view/pro-feature.php
CHANGED
@@ -32,7 +32,7 @@
|
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="tc">
|
35 |
-
<a class="button button-green mline" href="https://premium.wpmudev.org/project/wp-defender
|
36 |
<p class="is-marginless"><?php _e( "As part part of a WPMU DEV free trial.", wp_defender()->domain ) ?></p>
|
37 |
</div>
|
38 |
</div>
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="tc">
|
35 |
+
<a class="button button-green mline" href="https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade"><?php _e( "Get Defender Pro for Free", wp_defender()->domain ) ?></a>
|
36 |
<p class="is-marginless"><?php _e( "As part part of a WPMU DEV free trial.", wp_defender()->domain ) ?></p>
|
37 |
</div>
|
38 |
</div>
|
app/module/hardener/behavior/widget.php
CHANGED
@@ -31,7 +31,7 @@ class Widget extends Behavior {
|
|
31 |
<div class="box-content">
|
32 |
<?php $count = count( $issues ); ?>
|
33 |
<div class="line <?php echo $count ? 'end' : null ?>">
|
34 |
-
<?php _e( "
|
35 |
defense against hackers and bots.", wp_defender()->domain ) ?>
|
36 |
</div>
|
37 |
<?php if ( $count ): ?>
|
31 |
<div class="box-content">
|
32 |
<?php $count = count( $issues ); ?>
|
33 |
<div class="line <?php echo $count ? 'end' : null ?>">
|
34 |
+
<?php _e( "Defender checks for security tweaks you can make to enhance your website’s
|
35 |
defense against hackers and bots.", wp_defender()->domain ) ?>
|
36 |
</div>
|
37 |
<?php if ( $count ): ?>
|
app/module/hardener/component/disable-file-editor.php
CHANGED
@@ -27,6 +27,18 @@ class Disable_File_Editor extends Rule {
|
|
27 |
function addHooks() {
|
28 |
$this->add_action( 'processingHardener' . self::$slug, 'process' );
|
29 |
$this->add_action( 'processRevert' . self::$slug, 'revert' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
|
32 |
function revert() {
|
@@ -68,4 +80,36 @@ class Disable_File_Editor extends Rule {
|
|
68 |
|
69 |
return self::$service;
|
70 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
}
|
27 |
function addHooks() {
|
28 |
$this->add_action( 'processingHardener' . self::$slug, 'process' );
|
29 |
$this->add_action( 'processRevert' . self::$slug, 'revert' );
|
30 |
+
//Extra hardener actions incase setup is messed
|
31 |
+
if ( $this->check() ) {
|
32 |
+
$this->add_action( 'current_screen', 'current_screen' );
|
33 |
+
if ( is_network_admin() ) {
|
34 |
+
$this->add_action( 'network_admin_menu', 'editor_admin_menu', 999 );
|
35 |
+
} elseif ( is_user_admin() ) {
|
36 |
+
$this->add_action( 'user_admin_menu', 'editor_admin_menu', 999 );
|
37 |
+
} else {
|
38 |
+
$this->add_action( 'admin_menu', 'editor_admin_menu', 999 );
|
39 |
+
}
|
40 |
+
$this->add_filter( 'plugin_action_links', 'action_links', 10, 4 );
|
41 |
+
}
|
42 |
}
|
43 |
|
44 |
function revert() {
|
80 |
|
81 |
return self::$service;
|
82 |
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Sometimes the roles are messed in the installation
|
86 |
+
* So we manually check if the pages are accessed and disable access to the,
|
87 |
+
*/
|
88 |
+
function current_screen() {
|
89 |
+
$current_screen = get_current_screen();
|
90 |
+
if( $current_screen->id == 'theme-editor-network' || $current_screen->id == 'theme-editor' ){
|
91 |
+
wp_die('<p>'.__('Sorry, you are not allowed to edit templates for this site.').'</p>');
|
92 |
+
}
|
93 |
+
if( $current_screen->id == 'plugin-editor-network' || $current_screen->id == 'plugin-editor' ){
|
94 |
+
wp_die('<p>'.__('Sorry, you are not allowed to edit plugins for this site.').'</p>');
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Remove the edit in the admin menu
|
100 |
+
*/
|
101 |
+
function editor_admin_menu() {
|
102 |
+
remove_submenu_page( 'themes.php','theme-editor.php' );
|
103 |
+
remove_submenu_page( 'plugins.php','plugin-editor.php' );
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Remove any edit links from the plugin list
|
108 |
+
*
|
109 |
+
*/
|
110 |
+
function action_links( $actions, $plugin_file, $plugin_data, $context) {
|
111 |
+
if ( isset( $actions['edit'] ) )
|
112 |
+
unset( $actions['edit'] );
|
113 |
+
return $actions;
|
114 |
+
}
|
115 |
}
|
app/module/hardener/component/login-duration-service.php
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Paul Kevin
|
4 |
+
*/
|
5 |
+
|
6 |
+
namespace WP_Defender\Module\Hardener\Component;
|
7 |
+
|
8 |
+
use WP_Defender\Module\Hardener\IRule_Service;
|
9 |
+
use WP_Defender\Module\Hardener\Rule_Service;
|
10 |
+
use WP_Defender\Module\Hardener\Model\Settings;
|
11 |
+
|
12 |
+
class Login_Duration_Service extends Rule_Service implements IRule_Service {
|
13 |
+
|
14 |
+
const CACHE_KEY = 'login_duration';
|
15 |
+
const DURATION_CACHE_KEY = 'login_duration_days';
|
16 |
+
const DEFAULT_DAYS = 14;
|
17 |
+
|
18 |
+
protected $duration;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @param mixed $duration
|
22 |
+
*/
|
23 |
+
public function setDuration( $duration ) {
|
24 |
+
$this->duration = $duration;
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @return bool
|
29 |
+
*/
|
30 |
+
public function check() {
|
31 |
+
$key = Settings::instance()->getDValues( self::CACHE_KEY );
|
32 |
+
|
33 |
+
return ( $key == 1 );
|
34 |
+
}
|
35 |
+
|
36 |
+
public function process() {
|
37 |
+
Settings::instance()->setDValues( self::CACHE_KEY, 1 );
|
38 |
+
Settings::instance()->setDValues( self::DURATION_CACHE_KEY, $this->duration );
|
39 |
+
return true;
|
40 |
+
}
|
41 |
+
|
42 |
+
public function revert() {
|
43 |
+
Settings::instance()->setDValues( self::CACHE_KEY, 0 );
|
44 |
+
Settings::instance()->setDValues( self::DURATION_CACHE_KEY, self::DEFAULT_DAYS );
|
45 |
+
return true;
|
46 |
+
}
|
47 |
+
|
48 |
+
public function getDuration( $in_seconds = false ) {
|
49 |
+
$duration = Settings::instance()->getDValues( self::DURATION_CACHE_KEY );
|
50 |
+
if ( !empty( $duration ) ) {
|
51 |
+
$duration = intval( $duration );
|
52 |
+
return ( $in_seconds ) ? $duration * DAY_IN_SECONDS : $duration;
|
53 |
+
} else {
|
54 |
+
return ( $in_seconds ) ? self::DEFAULT_DAYS * DAY_IN_SECONDS : self::DEFAULT_DAYS;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
}
|
58 |
+
?>
|
app/module/hardener/component/login-duration.php
ADDED
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Paul Kevin
|
4 |
+
*/
|
5 |
+
|
6 |
+
namespace WP_Defender\Module\Hardener\Component;
|
7 |
+
|
8 |
+
use Hammer\Helper\WP_Helper;
|
9 |
+
use Hammer\Helper\HTTP_Helper;
|
10 |
+
use WP_Defender\Module\Hardener\Model\Settings;
|
11 |
+
use WP_Defender\Module\Hardener\Rule;
|
12 |
+
use WP_Defender\Behavior\Utils;
|
13 |
+
|
14 |
+
class Login_Duration extends Rule {
|
15 |
+
|
16 |
+
static $slug = 'login-duration';
|
17 |
+
|
18 |
+
static $service;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @return Login_Duration_Service
|
22 |
+
*/
|
23 |
+
public function getService() {
|
24 |
+
if ( self::$service == null ) {
|
25 |
+
self::$service = new Login_Duration_Service();
|
26 |
+
}
|
27 |
+
return self::$service;
|
28 |
+
}
|
29 |
+
|
30 |
+
function getDescription() {
|
31 |
+
$this->renderPartial( 'rules/login-duration' );
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @return string
|
36 |
+
*/
|
37 |
+
public function getTitle() {
|
38 |
+
return __( "Manage Login Duration", wp_defender()->domain );
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @return bool
|
43 |
+
*/
|
44 |
+
function check() {
|
45 |
+
return $this->getService()->check();
|
46 |
+
}
|
47 |
+
|
48 |
+
function addHooks() {
|
49 |
+
$this->add_action( 'processingHardener' . self::$slug, 'process' );
|
50 |
+
$this->add_action( 'processRevert' . self::$slug, 'revert' );
|
51 |
+
$this->add_action( 'wp_login', 'login_action_handler', 10, 2 );
|
52 |
+
if ( $this->check() ) {
|
53 |
+
$this->add_filter( 'auth_cookie_expiration', 'cookie_duration', 10, 3 );
|
54 |
+
$this->add_filter( 'login_message', 'login_message' );
|
55 |
+
$this->add_action( 'wp_loaded', 'check_login' );
|
56 |
+
}
|
57 |
+
|
58 |
+
}
|
59 |
+
|
60 |
+
function revert() {
|
61 |
+
if ( ! $this->verifyNonce() ) {
|
62 |
+
return;
|
63 |
+
}
|
64 |
+
$settings = Settings::instance();
|
65 |
+
$service = $this->getService();
|
66 |
+
$ret = $service->revert();
|
67 |
+
if ( ! is_wp_error( $ret ) ) {
|
68 |
+
Settings::instance()->addToIssues( self::$slug );
|
69 |
+
} else {
|
70 |
+
wp_send_json_error( array(
|
71 |
+
'message' => $ret->get_error_message()
|
72 |
+
) );
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
function process() {
|
77 |
+
if ( ! $this->verifyNonce() ) {
|
78 |
+
return;
|
79 |
+
}
|
80 |
+
$service = $this->getService();
|
81 |
+
$duration = HTTP_Helper::retrieve_post( 'duration' );
|
82 |
+
if ( is_numeric( $duration ) ) {
|
83 |
+
$service->setDuration( $duration );
|
84 |
+
$ret = $service->process();
|
85 |
+
if ( ! is_wp_error( $ret ) ) {
|
86 |
+
Settings::instance()->addToResolved( self::$slug );
|
87 |
+
} else {
|
88 |
+
wp_send_json_error( array(
|
89 |
+
'message' => $ret->get_error_message()
|
90 |
+
) );
|
91 |
+
}
|
92 |
+
} else {
|
93 |
+
wp_send_json_error( array(
|
94 |
+
'message' => __( 'Duration can only be a number', wp_defender()->domain )
|
95 |
+
) );
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Set the last login user meta
|
101 |
+
*/
|
102 |
+
function login_action_handler( $user_login, $user = '' ) {
|
103 |
+
if ( $user == '' ){
|
104 |
+
$user = get_user_by( 'login', $user_login );
|
105 |
+
}
|
106 |
+
if ( !$user ){
|
107 |
+
return;
|
108 |
+
}
|
109 |
+
$last_login_time = current_time( 'mysql' );
|
110 |
+
update_user_meta( $user->ID, 'last_login_time', $last_login_time );
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Check login of users
|
115 |
+
*/
|
116 |
+
function check_login() {
|
117 |
+
$defender_logout = HTTP_Helper::retrieve_get( 'defender_logout', false );
|
118 |
+
if( is_user_logged_in() ) {
|
119 |
+
if ( !$defender_logout ) {
|
120 |
+
$current_user = wp_get_current_user();
|
121 |
+
$user_id = $current_user->ID;
|
122 |
+
$current_time = current_time( 'mysql' );
|
123 |
+
$last_login_time = get_user_meta( $user_id, 'last_login_time', true );
|
124 |
+
$login_period = $this->getService()->getDuration( true );
|
125 |
+
if ( $last_login_time ) {
|
126 |
+
$diff = strtotime( $current_time ) - strtotime( $last_login_time );
|
127 |
+
if( $diff > $login_period ) {
|
128 |
+
$current_url = Utils::instance()->currentPageURL();
|
129 |
+
$after_logout_payload = array( 'redirect_to' => $current_url, 'msg'=>'session_expired' );
|
130 |
+
if ( is_multisite() ) {
|
131 |
+
set_site_transient( 'defender_logout_payload', $after_logout_payload, 30 * 60 );
|
132 |
+
}
|
133 |
+
set_transient( 'defender_logout_payload', $after_logout_payload, 30 * 60 );
|
134 |
+
$logout_url = add_query_arg( 'defender_logout', '1', site_url() );
|
135 |
+
wp_redirect( $logout_url );
|
136 |
+
exit;
|
137 |
+
}
|
138 |
+
} else {
|
139 |
+
//Incase the user already was logged in
|
140 |
+
$last_login_time = current_time( 'mysql' );
|
141 |
+
update_user_meta( $user_id, 'last_login_time', $last_login_time );
|
142 |
+
}
|
143 |
+
} else{
|
144 |
+
wp_logout();
|
145 |
+
$after_logout = HTTP_Helper::retrieve_get( 'after_logout', false );
|
146 |
+
if ( $after_logout ) {
|
147 |
+
$after_logout_url = esc_url( $after_logout );
|
148 |
+
wp_redirect( $after_logout_url );
|
149 |
+
exit;
|
150 |
+
}
|
151 |
+
$login_url = wp_login_url();
|
152 |
+
$logout_payload = ( is_multisite() ? get_site_transient( 'defender_logout_payload' ) : get_transient( 'defender_logout_payload' ) );
|
153 |
+
|
154 |
+
$login_url = add_query_arg( array(
|
155 |
+
'redirect_to' => $logout_payload['redirect_to'],
|
156 |
+
'defender_login_message' => $logout_payload['msg'],
|
157 |
+
), $login_url );
|
158 |
+
wp_redirect( $login_url );
|
159 |
+
exit;
|
160 |
+
}
|
161 |
+
} else if ( $defender_logout ) {
|
162 |
+
$after_logout = HTTP_Helper::retrieve_get( 'after_logout', false );
|
163 |
+
if ( $after_logout ) {
|
164 |
+
$after_logout_url = esc_url( $after_logout );
|
165 |
+
wp_redirect( $after_logout_url );
|
166 |
+
}
|
167 |
+
$login_url = wp_login_url();
|
168 |
+
$logout_payload = ( is_multisite() ? get_site_transient( 'defender_logout_payload' ) : get_transient( 'defender_logout_payload' ) );
|
169 |
+
|
170 |
+
$login_url = add_query_arg( array(
|
171 |
+
'redirect_to' => $logout_payload['redirect_to'],
|
172 |
+
'defender_login_message' => $logout_payload['msg'],
|
173 |
+
), $login_url );
|
174 |
+
wp_redirect( $login_url );
|
175 |
+
exit;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Handle the custom login message
|
182 |
+
*
|
183 |
+
*/
|
184 |
+
function login_message( $message = '' ) {
|
185 |
+
$login_msg = HTTP_Helper::retrieve_get( 'defender_login_message', false );
|
186 |
+
if( $login_msg ) {
|
187 |
+
$logout_msg = strip_tags( $login_msg );
|
188 |
+
if ( $logout_msg == 'session_expired' ) {
|
189 |
+
$duration = $this->getService()->getDuration( false );
|
190 |
+
$msg = sprintf( __( 'Your session has expired because it has been over %d days since your last login. Please log back in to continue.', wp_defender()->domain ), $duration );
|
191 |
+
$msg = htmlspecialchars( $msg, ENT_QUOTES, 'UTF-8' );
|
192 |
+
$message .= '<p class="login message">'. $msg . '</p>';
|
193 |
+
}
|
194 |
+
}
|
195 |
+
return $message;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Cookie duration in days in seconds
|
200 |
+
*
|
201 |
+
* @param Integer $duration - default duration
|
202 |
+
* @param Integer $user_id - current user id
|
203 |
+
* @param Boolean $remember - remember me login
|
204 |
+
*
|
205 |
+
* @return Integer $duration
|
206 |
+
*/
|
207 |
+
function cookie_duration( $duration, $user_id, $remember ) {
|
208 |
+
if ( $remember ) {
|
209 |
+
$duration = $this->getService()->getDuration( true );
|
210 |
+
}
|
211 |
+
return $duration;
|
212 |
+
}
|
213 |
+
|
214 |
+
}
|
215 |
+
|
216 |
+
?>
|
app/module/hardener/component/prevent-php.php
CHANGED
@@ -67,6 +67,7 @@ class Prevent_Php extends Rule {
|
|
67 |
function addHooks() {
|
68 |
$this->add_action( 'processingHardener' . self::$slug, 'process', 10, 2 );
|
69 |
$this->add_action( 'processRevert' . self::$slug, 'revert' );
|
|
|
70 |
}
|
71 |
|
72 |
function process() {
|
@@ -100,6 +101,36 @@ class Prevent_Php extends Rule {
|
|
100 |
}
|
101 |
}
|
102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
/**
|
104 |
* @return Prevent_PHP_Service
|
105 |
*/
|
67 |
function addHooks() {
|
68 |
$this->add_action( 'processingHardener' . self::$slug, 'process', 10, 2 );
|
69 |
$this->add_action( 'processRevert' . self::$slug, 'revert' );
|
70 |
+
$this->add_action( 'processUpdate' . self::$slug, 'update', 10, 2 );
|
71 |
}
|
72 |
|
73 |
function process() {
|
101 |
}
|
102 |
}
|
103 |
|
104 |
+
function update() {
|
105 |
+
if ( ! $this->verifyNonce() ) {
|
106 |
+
return;
|
107 |
+
}
|
108 |
+
$settings = Settings::instance();
|
109 |
+
$server = func_get_arg(0); //Get first param
|
110 |
+
$file_paths = func_get_arg(1); //Get second param
|
111 |
+
if ( in_array( $server, array( 'apache', 'litespeed' ) ) ) {
|
112 |
+
$service = $this->getApacheService();
|
113 |
+
$service->setHtConfig( $settings->getNewHtConfig() ); //Set the previous template
|
114 |
+
$service->unProtectContentDir(); //revert first
|
115 |
+
$service->setExcludeFilePaths( $file_paths ); //Set the paths
|
116 |
+
} else {
|
117 |
+
$service = $this->getService();
|
118 |
+
}
|
119 |
+
$ret = $service->process();
|
120 |
+
if ( ! is_wp_error( $ret ) ) {
|
121 |
+
if ( in_array( $server, array( 'apache', 'litespeed' ) ) ) {
|
122 |
+
$settings->saveExcludedFilePaths( $service->getExcludedFilePaths() );
|
123 |
+
$settings->saveNewHtConfig( $service->getNewHtConfig() );
|
124 |
+
}
|
125 |
+
$settings->setActiveServer( $server );
|
126 |
+
$settings->save();
|
127 |
+
} else {
|
128 |
+
wp_send_json_error( array(
|
129 |
+
'message' => $ret->get_error_message()
|
130 |
+
) );
|
131 |
+
}
|
132 |
+
}
|
133 |
+
|
134 |
/**
|
135 |
* @return Prevent_PHP_Service
|
136 |
*/
|
app/module/hardener/component/security-key.php
CHANGED
@@ -16,14 +16,19 @@ class Security_Key extends Rule {
|
|
16 |
static $service;
|
17 |
|
18 |
function getDescription() {
|
19 |
-
$
|
|
|
|
|
|
|
|
|
|
|
20 |
if ( $time ) {
|
21 |
$daysAgo = ( time() - $time ) / ( 60 * 60 * 24 );
|
22 |
} else {
|
23 |
$daysAgo = null;
|
24 |
}
|
25 |
$this->renderPartial( 'rules/security-key', array(
|
26 |
-
'interval' =>
|
27 |
'daysAgo' => $daysAgo
|
28 |
) );
|
29 |
}
|
@@ -52,8 +57,8 @@ class Security_Key extends Rule {
|
|
52 |
$reminder = HTTP_Helper::retrieve_post( 'remind_date', null );
|
53 |
if ( $reminder ) {
|
54 |
$settings = Settings::instance();
|
|
|
55 |
$settings->setDValues( 'securityReminderDate', strtotime( '+' . $reminder, current_time( 'timestamp' ) ) );
|
56 |
-
$settings->save();
|
57 |
die;
|
58 |
}
|
59 |
}
|
16 |
static $service;
|
17 |
|
18 |
function getDescription() {
|
19 |
+
$settings = Settings::instance();
|
20 |
+
$time = $settings->getDValues( Security_Key_Service::CACHE_KEY );
|
21 |
+
$interval = $settings->getDValues( 'securityReminderDuration' );
|
22 |
+
if ( !$interval ) {
|
23 |
+
$interval = Security_Key_Service::DEFAULT_DAYS;
|
24 |
+
}
|
25 |
if ( $time ) {
|
26 |
$daysAgo = ( time() - $time ) / ( 60 * 60 * 24 );
|
27 |
} else {
|
28 |
$daysAgo = null;
|
29 |
}
|
30 |
$this->renderPartial( 'rules/security-key', array(
|
31 |
+
'interval' => $interval,
|
32 |
'daysAgo' => $daysAgo
|
33 |
) );
|
34 |
}
|
57 |
$reminder = HTTP_Helper::retrieve_post( 'remind_date', null );
|
58 |
if ( $reminder ) {
|
59 |
$settings = Settings::instance();
|
60 |
+
$settings->setDValues( 'securityReminderDuration', $reminder );
|
61 |
$settings->setDValues( 'securityReminderDate', strtotime( '+' . $reminder, current_time( 'timestamp' ) ) );
|
|
|
62 |
die;
|
63 |
}
|
64 |
}
|
app/module/hardener/component/servers/apache-service.php
CHANGED
@@ -171,7 +171,13 @@ class Apache_Service extends Rule_Service implements IRule_Service {
|
|
171 |
$default = $this->new_htconfig;
|
172 |
}
|
173 |
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
$htConfig = trim( $htConfig );
|
176 |
file_put_contents( $htPath, $htConfig, LOCK_EX );
|
177 |
}
|
171 |
$default = $this->new_htconfig;
|
172 |
}
|
173 |
|
174 |
+
//Introduced regex
|
175 |
+
preg_match_all('/## WP Defender(.*?)## WP Defender - End ##/s', $htConfig, $matches);
|
176 |
+
if ( is_array( $matches ) && count( $matches ) > 0 ) {
|
177 |
+
$htConfig = str_replace( implode( '', $matches[0] ), '', $htConfig );
|
178 |
+
} else {
|
179 |
+
$htConfig = str_replace( implode( '', $default ), '', $htConfig );
|
180 |
+
}
|
181 |
$htConfig = trim( $htConfig );
|
182 |
file_put_contents( $htPath, $htConfig, LOCK_EX );
|
183 |
}
|
app/module/hardener/controller/main.php
CHANGED
@@ -42,6 +42,7 @@ class Main extends Controller {
|
|
42 |
$this->add_ajax_action( 'processRevert', 'processRevert' );
|
43 |
$this->add_ajax_action( 'ignoreHardener', 'ignoreHardener' );
|
44 |
$this->add_ajax_action( 'restoreHardener', 'restoreHardener' );
|
|
|
45 |
}
|
46 |
|
47 |
public function restoreHardener() {
|
@@ -121,6 +122,35 @@ class Main extends Controller {
|
|
121 |
) );
|
122 |
}
|
123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
/**
|
125 |
* Add submit admin page
|
126 |
*/
|
42 |
$this->add_ajax_action( 'processRevert', 'processRevert' );
|
43 |
$this->add_ajax_action( 'ignoreHardener', 'ignoreHardener' );
|
44 |
$this->add_ajax_action( 'restoreHardener', 'restoreHardener' );
|
45 |
+
$this->add_ajax_action( 'updateHardener', 'updateHardener' );
|
46 |
}
|
47 |
|
48 |
public function restoreHardener() {
|
122 |
) );
|
123 |
}
|
124 |
|
125 |
+
/**
|
126 |
+
* Update Hardener
|
127 |
+
* Update existing rules
|
128 |
+
*/
|
129 |
+
public function updateHardener() {
|
130 |
+
if ( ! $this->checkPermission() ) {
|
131 |
+
return;
|
132 |
+
}
|
133 |
+
|
134 |
+
$slug = HTTP_Helper::retrieve_post( 'slug' );
|
135 |
+
$file_paths = HTTP_Helper::retrieve_post( 'file_paths' ); //File paths to ignore. Apache and litespeed mainly
|
136 |
+
if ( $file_paths ) {
|
137 |
+
$file_paths = sanitize_textarea_field( $file_paths );
|
138 |
+
} else {
|
139 |
+
$file_paths = '';
|
140 |
+
}
|
141 |
+
|
142 |
+
$server = HTTP_Helper::retrieve_post( 'current_server' ); //Current server
|
143 |
+
do_action( "processUpdate" . $slug , $server, $file_paths );
|
144 |
+
//fall back
|
145 |
+
wp_send_json_success( array(
|
146 |
+
'message' => __( "Security tweak successfully updated.", wp_defender()->domain ),
|
147 |
+
'issues' => $this->getCount( 'issues' ),
|
148 |
+
'fixed' => $this->getCount( 'fixed' ),
|
149 |
+
'ignore' => $this->getCount( 'ignore' ),
|
150 |
+
'update' => false
|
151 |
+
) );
|
152 |
+
}
|
153 |
+
|
154 |
/**
|
155 |
* Add submit admin page
|
156 |
*/
|
app/module/hardener/js/scripts.js
CHANGED
@@ -37,6 +37,9 @@ jQuery(function ($) {
|
|
37 |
});
|
38 |
$('span.hardener-nginx-extra-instructions').html(newRule);
|
39 |
}
|
|
|
|
|
|
|
40 |
});
|
41 |
|
42 |
/**
|
@@ -50,6 +53,13 @@ jQuery(function ($) {
|
|
50 |
}
|
51 |
});
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
/**
|
54 |
* Server select
|
55 |
*/
|
@@ -66,6 +76,11 @@ jQuery(function ($) {
|
|
66 |
});
|
67 |
$('.hardener-instructions-'+selected).removeClass('wd-hide');
|
68 |
}
|
|
|
|
|
|
|
|
|
|
|
69 |
|
70 |
});
|
71 |
|
@@ -96,14 +111,20 @@ jQuery(function ($) {
|
|
96 |
} else {
|
97 |
$('.count-resolved').addClass('wd-hide');
|
98 |
}
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
} else {
|
108 |
Defender.showNotification('error', data.data.message);
|
109 |
}
|
37 |
});
|
38 |
$('span.hardener-nginx-extra-instructions').html(newRule);
|
39 |
}
|
40 |
+
if ( $('.hardener-instructions-apache-litespeed').length ) {
|
41 |
+
$('.hardener-update-frm [name="file_paths"]').val(text_val);
|
42 |
+
}
|
43 |
});
|
44 |
|
45 |
/**
|
53 |
}
|
54 |
});
|
55 |
|
56 |
+
/**
|
57 |
+
* Toggle text area
|
58 |
+
*/
|
59 |
+
$(document).on('click','button.hardener-php-excuted-execption', function(){
|
60 |
+
$('.hardener-instructions textarea.hardener-php-excuted-ignore').toggle('fast');
|
61 |
+
});
|
62 |
+
|
63 |
/**
|
64 |
* Server select
|
65 |
*/
|
76 |
});
|
77 |
$('.hardener-instructions-'+selected).removeClass('wd-hide');
|
78 |
}
|
79 |
+
if( selected == 'apache' || selected == 'litespeed' || selected == 'nginx'){
|
80 |
+
$('.hardener-instructions-extra-exceptions').removeClass('wd-hide');
|
81 |
+
}else{
|
82 |
+
$('.hardener-instructions-extra-exceptions').addClass('wd-hide');
|
83 |
+
}
|
84 |
|
85 |
});
|
86 |
|
111 |
} else {
|
112 |
$('.count-resolved').addClass('wd-hide');
|
113 |
}
|
114 |
+
var update_rules = true;
|
115 |
+
if ( typeof data.data.update !== "undefined" ) {
|
116 |
+
update_rules = false;
|
117 |
+
}
|
118 |
+
if ( update_rules ) {
|
119 |
+
form.closest('.rule').slideUp(500, function () {
|
120 |
+
$(this).remove();
|
121 |
+
if ($('.rule').size() == 0) {
|
122 |
+
setTimeout(function () {
|
123 |
+
location.reload();
|
124 |
+
}, 500)
|
125 |
+
}
|
126 |
+
});
|
127 |
+
}
|
128 |
} else {
|
129 |
Defender.showNotification('error', data.data.message);
|
130 |
}
|
app/module/hardener/model/settings.php
CHANGED
@@ -8,22 +8,16 @@ namespace WP_Defender\Module\Hardener\Model;
|
|
8 |
use Hammer\Helper\WP_Helper;
|
9 |
use WP_Defender\Behavior\Utils;
|
10 |
use WP_Defender\Module\Hardener\Component\Change_Admin;
|
11 |
-
use WP_Defender\Module\Hardener\Component\Change_Admin_Service;
|
12 |
use WP_Defender\Module\Hardener\Component\DB_Prefix;
|
13 |
-
use WP_Defender\Module\Hardener\Component\DB_Prefix_Service;
|
14 |
use WP_Defender\Module\Hardener\Component\Disable_File_Editor;
|
15 |
-
use WP_Defender\Module\Hardener\Component\Disable_File_Editor_Service;
|
16 |
use WP_Defender\Module\Hardener\Component\Disable_Trackback;
|
17 |
-
use WP_Defender\Module\Hardener\Component\Disable_Trackback_Service;
|
18 |
use WP_Defender\Module\Hardener\Component\Hide_Error;
|
19 |
-
use WP_Defender\Module\Hardener\Component\
|
20 |
use WP_Defender\Module\Hardener\Component\PHP_Version;
|
21 |
use WP_Defender\Module\Hardener\Component\Prevent_Php;
|
22 |
use WP_Defender\Module\Hardener\Component\Protect_Information;
|
23 |
use WP_Defender\Module\Hardener\Component\Security_Key;
|
24 |
-
use WP_Defender\Module\Hardener\Component\Security_Key_Service;
|
25 |
use WP_Defender\Module\Hardener\Component\WP_Version;
|
26 |
-
use WP_Defender\Module\Hardener\Component\WP_Version_Service;
|
27 |
use WP_Defender\Module\Hardener\Rule;
|
28 |
use WP_Defender\Module\Hardener\Rule_Service;
|
29 |
|
@@ -269,7 +263,8 @@ class Settings extends \Hammer\WP\Settings {
|
|
269 |
Hide_Error::$slug => $init == true ? new Hide_Error() : Hide_Error::getClassName(),
|
270 |
Security_Key::$slug => $init == true ? new Security_Key() : Security_Key::getClassName(),
|
271 |
Protect_Information::$slug => $init == true ? new Protect_Information() : Protect_Information::getClassName(),
|
272 |
-
Prevent_Php::$slug => $init == true ? new Prevent_Php() : Prevent_Php::getClassName()
|
|
|
273 |
);
|
274 |
}
|
275 |
|
8 |
use Hammer\Helper\WP_Helper;
|
9 |
use WP_Defender\Behavior\Utils;
|
10 |
use WP_Defender\Module\Hardener\Component\Change_Admin;
|
|
|
11 |
use WP_Defender\Module\Hardener\Component\DB_Prefix;
|
|
|
12 |
use WP_Defender\Module\Hardener\Component\Disable_File_Editor;
|
|
|
13 |
use WP_Defender\Module\Hardener\Component\Disable_Trackback;
|
|
|
14 |
use WP_Defender\Module\Hardener\Component\Hide_Error;
|
15 |
+
use WP_Defender\Module\Hardener\Component\Login_Duration;
|
16 |
use WP_Defender\Module\Hardener\Component\PHP_Version;
|
17 |
use WP_Defender\Module\Hardener\Component\Prevent_Php;
|
18 |
use WP_Defender\Module\Hardener\Component\Protect_Information;
|
19 |
use WP_Defender\Module\Hardener\Component\Security_Key;
|
|
|
20 |
use WP_Defender\Module\Hardener\Component\WP_Version;
|
|
|
21 |
use WP_Defender\Module\Hardener\Rule;
|
22 |
use WP_Defender\Module\Hardener\Rule_Service;
|
23 |
|
263 |
Hide_Error::$slug => $init == true ? new Hide_Error() : Hide_Error::getClassName(),
|
264 |
Security_Key::$slug => $init == true ? new Security_Key() : Security_Key::getClassName(),
|
265 |
Protect_Information::$slug => $init == true ? new Protect_Information() : Protect_Information::getClassName(),
|
266 |
+
Prevent_Php::$slug => $init == true ? new Prevent_Php() : Prevent_Php::getClassName(),
|
267 |
+
Login_Duration::$slug => $init == true ? new Login_Duration() : Login_Duration::getClassName()
|
268 |
);
|
269 |
}
|
270 |
|
app/module/hardener/view/rules/change-admin.php
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
<?php $controller->createNonceField(); ?>
|
29 |
<input type="hidden" name="action" value="processHardener"/>
|
30 |
<input type="text" placeholder="<?php esc_attr_e( "Enter new username", wp_defender()->domain ) ?>"
|
31 |
-
name="username" class="block"
|
32 |
<input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
|
33 |
<button class="button float-r"
|
34 |
type="submit"><?php _e( "Update", wp_defender()->domain ) ?></button>
|
28 |
<?php $controller->createNonceField(); ?>
|
29 |
<input type="hidden" name="action" value="processHardener"/>
|
30 |
<input type="text" placeholder="<?php esc_attr_e( "Enter new username", wp_defender()->domain ) ?>"
|
31 |
+
name="username" class="block" />
|
32 |
<input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
|
33 |
<button class="button float-r"
|
34 |
type="submit"><?php _e( "Update", wp_defender()->domain ) ?></button>
|
app/module/hardener/view/rules/login-duration.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="rule closed" id="login-duration">
|
2 |
+
<div class="rule-title">
|
3 |
+
<?php if ( $controller->check() == false ): ?>
|
4 |
+
<i class="def-icon icon-warning"></i>
|
5 |
+
<?php else: ?>
|
6 |
+
<i class="def-icon icon-tick"></i>
|
7 |
+
<?php endif; ?>
|
8 |
+
<?php echo $controller->getTitle() ?>
|
9 |
+
</div>
|
10 |
+
<div class="rule-content">
|
11 |
+
<h3><?php _e( "Overview", wp_defender()->domain ) ?></h3>
|
12 |
+
<div class="line end">
|
13 |
+
<?php _e( "By default, users who select the 'remember me' option stay logged in for 14 days", wp_defender()->domain ) ?>
|
14 |
+
</div>
|
15 |
+
<h3>
|
16 |
+
<?php _e( "How to fix", wp_defender()->domain ) ?>
|
17 |
+
</h3>
|
18 |
+
<div class="well">
|
19 |
+
<?php
|
20 |
+
$setting = \WP_Defender\Module\Hardener\Model\Settings::instance();
|
21 |
+
|
22 |
+
if ( $controller->check() ):
|
23 |
+
?>
|
24 |
+
<p class="line"><?php esc_attr_e( sprintf( __('Login Duration is locked down. Current duration is %d days', wp_defender()->domain ), $controller->getService()->getDuration() ) ); ?></p>
|
25 |
+
<form method="post" class="hardener-frm rule-process">
|
26 |
+
<?php $controller->createNonceField(); ?>
|
27 |
+
<input type="hidden" name="action" value="processRevert"/>
|
28 |
+
<input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
|
29 |
+
<button class="button button-small button-grey" type="submit"><?php _e( "Revert", wp_defender()->domain ) ?></button>
|
30 |
+
</form>
|
31 |
+
<?php
|
32 |
+
else:
|
33 |
+
?>
|
34 |
+
<div class="line">
|
35 |
+
<p><?php _e( "Please change the number of days a user can stay logged in", wp_defender()->domain ) ?></p>
|
36 |
+
</div>
|
37 |
+
<form method="post" class="hardener-frm rule-process">
|
38 |
+
<?php $controller->createNonceField(); ?>
|
39 |
+
<input type="hidden" name="action" value="processHardener"/>
|
40 |
+
<input type="text" placeholder="<?php esc_attr_e( "Enter number of days", wp_defender()->domain ) ?>"
|
41 |
+
name="duration" class="block" />
|
42 |
+
<input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
|
43 |
+
<button class="button float-r"
|
44 |
+
type="submit"><?php _e( "Update", wp_defender()->domain ) ?></button>
|
45 |
+
</form>
|
46 |
+
<?php $controller->showIgnoreForm() ?>
|
47 |
+
<div class="clear"></div>
|
48 |
+
<?php
|
49 |
+
endif;
|
50 |
+
?>
|
51 |
+
</div>
|
52 |
+
</div>
|
53 |
+
</div>
|
app/module/hardener/view/rules/prevent-php-executed.php
CHANGED
@@ -16,8 +16,34 @@
|
|
16 |
<?php _e( "How to fix", wp_defender()->domain ) ?>
|
17 |
</h3>
|
18 |
<div class="well">
|
19 |
-
<?php
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
<form method="post" class="hardener-frm rule-process">
|
22 |
<?php $controller->createNonceField(); ?>
|
23 |
<input type="hidden" name="action" value="processRevert"/>
|
@@ -26,8 +52,8 @@
|
|
26 |
type="submit"><?php _e( "Revert", wp_defender()->domain ) ?></button>
|
27 |
</form>
|
28 |
<?php else:
|
29 |
-
$servers
|
30 |
-
|
31 |
if ( DIRECTORY_SEPARATOR == '\\' ) {
|
32 |
//Windows
|
33 |
$wp_includes = str_replace( ABSPATH, '', WPINC );
|
@@ -64,10 +90,6 @@
|
|
64 |
<div class="line">
|
65 |
<p><?php _e( "We will place <strong>.htaccess</strong> file into the root folder to lock down the files and folders inside.", wp_defender()->domain ) ?></p>
|
66 |
</div>
|
67 |
-
<div class="line">
|
68 |
-
<p><?php _e( "File paths to ignore in the /wp-content directory (each in a new line). The file index.php is not allowed", wp_defender()->domain ) ?></p>
|
69 |
-
<textarea class="hardener-php-excuted-ignore"></textarea>
|
70 |
-
</div>
|
71 |
<form method="post" class="hardener-frm hardener-apache-frm rule-process">
|
72 |
<?php $controller->createNonceField(); ?>
|
73 |
<input type="hidden" name="action" value="processHardener"/>
|
@@ -82,10 +104,6 @@
|
|
82 |
<div class="line">
|
83 |
<p><?php _e( "We will place <strong>.htaccess</strong> file into the root folder to lock down the files and folders inside.", wp_defender()->domain ) ?></p>
|
84 |
</div>
|
85 |
-
<div class="line">
|
86 |
-
<p><?php _e( "File paths to ignore in the /wp-content directory (each in a new line). The file index.php is not allowed", wp_defender()->domain ) ?></p>
|
87 |
-
<textarea class="hardener-php-excuted-ignore"></textarea>
|
88 |
-
</div>
|
89 |
<form method="post" class="hardener-frm hardener-litespeed-frm rule-process">
|
90 |
<?php $controller->createNonceField(); ?>
|
91 |
<input type="hidden" name="action" value="processHardener"/>
|
@@ -119,10 +137,6 @@ location ~* ^$wp_content/.*\.php$ {
|
|
119 |
|
120 |
<p><?php esc_html_e( "For NGINX servers:", wp_defender()->domain ) ?></p>
|
121 |
<ol>
|
122 |
-
<li>
|
123 |
-
<p><?php _e( "Input the file paths to ignore in the /wp-content directory (each in a new line). The file index.php is not allowed", wp_defender()->domain ) ?></p>
|
124 |
-
<textarea class="hardener-php-excuted-ignore"></textarea>
|
125 |
-
</li>
|
126 |
<li>
|
127 |
<?php esc_html_e( "Copy the generated code into your site specific .conf file usually located in a subdirectory under /etc/nginx/... or /usr/local/nginx/conf/...", wp_defender()->domain ) ?>
|
128 |
</li>
|
@@ -164,8 +178,25 @@ location ~* ^$wp_content/.*\.php$ {
|
|
164 |
</form>
|
165 |
|
166 |
</div>
|
167 |
-
<?php $controller->showIgnoreForm()
|
168 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
</div>
|
170 |
</div>
|
171 |
</div>
|
16 |
<?php _e( "How to fix", wp_defender()->domain ) ?>
|
17 |
</h3>
|
18 |
<div class="well">
|
19 |
+
<?php
|
20 |
+
$setting = \WP_Defender\Module\Hardener\Model\Settings::instance();
|
21 |
+
|
22 |
+
if ( $controller->check() ): ?>
|
23 |
+
<p class="line"><?php _e( "PHP execution is locked down.", wp_defender()->domain ) ?>
|
24 |
+
<?php
|
25 |
+
if ( in_array( $setting->active_server, array( 'apache', 'litespeed' ) ) ) {
|
26 |
+
$file_paths = $setting->getExcludedFilePaths();
|
27 |
+
if ( !empty( $file_paths ) && is_array( $file_paths ) && count( $file_paths ) > 0 ) {
|
28 |
+
_e(" The following file paths have been allowed in the /wp-content directory :", wp_defender()->domain );
|
29 |
+
?>
|
30 |
+
<div class="hardener-instructions hardener-instructions-apache-litespeed">
|
31 |
+
<textarea class="hardener-php-excuted-ignore"><?php echo implode( "\n", $file_paths ); ?></textarea>
|
32 |
+
<form method="post" class="hardener-frm hardener-update-frm rule-process">
|
33 |
+
<?php $controller->createNonceField(); ?>
|
34 |
+
<input type="hidden" name="action" value="updateHardener"/>
|
35 |
+
<input type="hidden" name="file_paths" value="<?php echo implode( "\n", $file_paths ); ?>"/>
|
36 |
+
<input type="hidden" name="current_server" value="<?php echo $setting->active_server; ?>"/>
|
37 |
+
<input type="hidden" name="slug" value="<?php echo $controller::$slug ?>"/>
|
38 |
+
<button class="button button-small float-r"
|
39 |
+
type="submit"><?php _e( "Update .htaccess file", wp_defender()->domain ) ?></button>
|
40 |
+
</form>
|
41 |
+
</div>
|
42 |
+
<?php
|
43 |
+
}
|
44 |
+
}
|
45 |
+
?>
|
46 |
+
</p>
|
47 |
<form method="post" class="hardener-frm rule-process">
|
48 |
<?php $controller->createNonceField(); ?>
|
49 |
<input type="hidden" name="action" value="processRevert"/>
|
52 |
type="submit"><?php _e( "Revert", wp_defender()->domain ) ?></button>
|
53 |
</form>
|
54 |
<?php else:
|
55 |
+
$servers = \WP_Defender\Behavior\Utils::instance()->serverTypes();
|
56 |
+
|
57 |
if ( DIRECTORY_SEPARATOR == '\\' ) {
|
58 |
//Windows
|
59 |
$wp_includes = str_replace( ABSPATH, '', WPINC );
|
90 |
<div class="line">
|
91 |
<p><?php _e( "We will place <strong>.htaccess</strong> file into the root folder to lock down the files and folders inside.", wp_defender()->domain ) ?></p>
|
92 |
</div>
|
|
|
|
|
|
|
|
|
93 |
<form method="post" class="hardener-frm hardener-apache-frm rule-process">
|
94 |
<?php $controller->createNonceField(); ?>
|
95 |
<input type="hidden" name="action" value="processHardener"/>
|
104 |
<div class="line">
|
105 |
<p><?php _e( "We will place <strong>.htaccess</strong> file into the root folder to lock down the files and folders inside.", wp_defender()->domain ) ?></p>
|
106 |
</div>
|
|
|
|
|
|
|
|
|
107 |
<form method="post" class="hardener-frm hardener-litespeed-frm rule-process">
|
108 |
<?php $controller->createNonceField(); ?>
|
109 |
<input type="hidden" name="action" value="processHardener"/>
|
137 |
|
138 |
<p><?php esc_html_e( "For NGINX servers:", wp_defender()->domain ) ?></p>
|
139 |
<ol>
|
|
|
|
|
|
|
|
|
140 |
<li>
|
141 |
<?php esc_html_e( "Copy the generated code into your site specific .conf file usually located in a subdirectory under /etc/nginx/... or /usr/local/nginx/conf/...", wp_defender()->domain ) ?>
|
142 |
</li>
|
178 |
</form>
|
179 |
|
180 |
</div>
|
181 |
+
<?php $controller->showIgnoreForm();
|
182 |
+
$prevent_php_style = "style='display:none'";
|
183 |
+
if ( in_array( $setting->active_server, array( 'apache', 'litespeed', 'nginx' ) ) ) {
|
184 |
+
$prevent_php_style = "style='display:block'";
|
185 |
+
}
|
186 |
+
?>
|
187 |
+
<div <?php echo $prevent_php_style; ?> class="hardener-instructions hardener-instructions-extra-exceptions">
|
188 |
+
<h3>
|
189 |
+
<?php _e( "Exceptions", wp_defender()->domain ) ?>
|
190 |
+
</h3>
|
191 |
+
<div class="line">
|
192 |
+
<p><?php _e( "By default Defender will lock down directories WordPress doesn't need to allow PHP execution for. However, if you have specific files you need to allow PHP execution for you can add exceptions. Add file name one per line", wp_defender()->domain ) ?></p>
|
193 |
+
<button class="button button-grey hardener-php-excuted-execption" type="button"><?php _e( "Add Exception", wp_defender()->domain ) ?></button>
|
194 |
+
</div>
|
195 |
+
<div class="line">
|
196 |
+
<textarea class="hardener-php-excuted-ignore" style='display:none'></textarea>
|
197 |
+
</div>
|
198 |
+
</div>
|
199 |
+
<?php endif; ?>
|
200 |
</div>
|
201 |
</div>
|
202 |
</div>
|
app/module/ip-lockout/component/login-protection-api.php
CHANGED
@@ -40,15 +40,13 @@ class Login_Protection_Api extends Component {
|
|
40 |
}
|
41 |
}
|
42 |
|
43 |
-
$
|
44 |
'ip' => $log->ip,
|
45 |
'type' => Log_Model::AUTH_FAIL,
|
46 |
'blog_id' => get_current_blog_id(),
|
47 |
'date' => array( 'compare' => '>=', 'value' => $after )
|
48 |
) );
|
49 |
|
50 |
-
|
51 |
-
$attempt = count( $logs );
|
52 |
if ( ! is_object( $model ) ) {
|
53 |
//no record, create one
|
54 |
$model = new IP_Model();
|
@@ -173,6 +171,7 @@ class Login_Protection_Api extends Component {
|
|
173 |
|
174 |
/**
|
175 |
* @param null $time - unix timestamp
|
|
|
176 |
* @deprecated
|
177 |
* @return int
|
178 |
*/
|
@@ -190,6 +189,7 @@ class Login_Protection_Api extends Component {
|
|
190 |
|
191 |
/**
|
192 |
* @param null $time - unix timestamp
|
|
|
193 |
* @deprecated
|
194 |
* @return int
|
195 |
*/
|
@@ -283,7 +283,7 @@ class Login_Protection_Api extends Component {
|
|
283 |
$data[] = $line;
|
284 |
|
285 |
}
|
286 |
-
fclose( $
|
287 |
|
288 |
return $data;
|
289 |
}
|
@@ -385,4 +385,55 @@ class Login_Protection_Api extends Component {
|
|
385 |
|
386 |
return false;
|
387 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
}
|
40 |
}
|
41 |
}
|
42 |
|
43 |
+
$attempt = Log_Model::count( array(
|
44 |
'ip' => $log->ip,
|
45 |
'type' => Log_Model::AUTH_FAIL,
|
46 |
'blog_id' => get_current_blog_id(),
|
47 |
'date' => array( 'compare' => '>=', 'value' => $after )
|
48 |
) );
|
49 |
|
|
|
|
|
50 |
if ( ! is_object( $model ) ) {
|
51 |
//no record, create one
|
52 |
$model = new IP_Model();
|
171 |
|
172 |
/**
|
173 |
* @param null $time - unix timestamp
|
174 |
+
*
|
175 |
* @deprecated
|
176 |
* @return int
|
177 |
*/
|
189 |
|
190 |
/**
|
191 |
* @param null $time - unix timestamp
|
192 |
+
*
|
193 |
* @deprecated
|
194 |
* @return int
|
195 |
*/
|
283 |
$data[] = $line;
|
284 |
|
285 |
}
|
286 |
+
fclose( $fp );
|
287 |
|
288 |
return $data;
|
289 |
}
|
385 |
|
386 |
return false;
|
387 |
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
*
|
391 |
+
*/
|
392 |
+
public static function createTables() {
|
393 |
+
global $wpdb;
|
394 |
+
|
395 |
+
$charsetCollate = $wpdb->get_charset_collate();
|
396 |
+
$tableName1 = $wpdb->base_prefix . 'defender_lockout';
|
397 |
+
$tableName2 = $wpdb->base_prefix . 'defender_lockout_log';
|
398 |
+
$sql = "CREATE TABLE IF NOT EXISTS `{$tableName1}` (
|
399 |
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
400 |
+
`ip` varchar(255) DEFAULT NULL,
|
401 |
+
`status` varchar(16) DEFAULT NULL,
|
402 |
+
`lockout_message` text,
|
403 |
+
`release_time` int(11) DEFAULT NULL,
|
404 |
+
`lock_time` int(11) DEFAULT NULL,
|
405 |
+
`lock_time_404` int(11) DEFAULT NULL,
|
406 |
+
`attempt` int(11) DEFAULT NULL,
|
407 |
+
`attempt_404` int(11) DEFAULT NULL,
|
408 |
+
PRIMARY KEY (`id`)
|
409 |
+
) $charsetCollate;
|
410 |
+
CREATE TABLE `{$tableName2}` (
|
411 |
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
412 |
+
`log` text,
|
413 |
+
`ip` varchar(255) DEFAULT NULL,
|
414 |
+
`date` int(11) DEFAULT NULL,
|
415 |
+
`type` varchar(16) DEFAULT NULL,
|
416 |
+
`user_agent` varchar(255) DEFAULT NULL,
|
417 |
+
`blog_id` int(11) DEFAULT NULL,
|
418 |
+
PRIMARY KEY (`id`)
|
419 |
+
) $charsetCollate;
|
420 |
+
";
|
421 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
422 |
+
dbDelta( $sql );
|
423 |
+
}
|
424 |
+
|
425 |
+
/**
|
426 |
+
* @return bool
|
427 |
+
*/
|
428 |
+
public static function checkIfTableExists() {
|
429 |
+
global $wpdb;
|
430 |
+
$tableName1 = $wpdb->base_prefix . 'defender_lockout';
|
431 |
+
$tableName2 = $wpdb->base_prefix . 'defender_lockout_log';
|
432 |
+
if ( $wpdb->get_var( "SHOW TABLES LIKE '$tableName1'" ) != $tableName1 ||
|
433 |
+
$wpdb->get_var( "SHOW TABLES LIKE '$tableName2'" ) != $tableName2 ) {
|
434 |
+
return false;
|
435 |
+
}
|
436 |
+
|
437 |
+
return true;
|
438 |
+
}
|
439 |
}
|
app/module/ip-lockout/controller/main.php
CHANGED
@@ -8,13 +8,16 @@ namespace WP_Defender\Module\IP_Lockout\Controller;
|
|
8 |
use Hammer\Helper\HTTP_Helper;
|
9 |
use Hammer\Helper\Log_Helper;
|
10 |
use Hammer\Helper\WP_Helper;
|
|
|
11 |
use WP_Defender\Controller;
|
12 |
use WP_Defender\Module\Audit\Component\Audit_API;
|
13 |
use WP_Defender\Module\IP_Lockout\Behavior\IP_Lockout;
|
14 |
use WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api;
|
15 |
use WP_Defender\Module\IP_Lockout\Component\Logs_Table;
|
16 |
use WP_Defender\Module\IP_Lockout\Model\IP_Model;
|
|
|
17 |
use WP_Defender\Module\IP_Lockout\Model\Log_Model;
|
|
|
18 |
use WP_Defender\Module\IP_Lockout\Model\Settings;
|
19 |
use WP_Defender\Vendor\Email_Search;
|
20 |
|
@@ -58,6 +61,7 @@ class Main extends Controller {
|
|
58 |
$this->add_ajax_action( 'lockoutIPAction', 'lockoutIPAction' );
|
59 |
$this->add_ajax_action( 'lockoutEmptyLogs', 'lockoutEmptyLogs' );
|
60 |
$this->add_ajax_action( 'lockoutSummaryData', 'lockoutSummaryData' );
|
|
|
61 |
|
62 |
$this->handleIpAction();
|
63 |
$this->handleUserSearch();
|
@@ -72,8 +76,6 @@ class Main extends Controller {
|
|
72 |
return;
|
73 |
}
|
74 |
|
75 |
-
$setting = Settings::instance();
|
76 |
-
|
77 |
$lockouts = Log_Model::findAll( array(
|
78 |
'type' => array(
|
79 |
Log_Model::LOCKOUT_404,
|
@@ -81,9 +83,9 @@ class Main extends Controller {
|
|
81 |
),
|
82 |
'date' => array(
|
83 |
'compare' => '>=',
|
84 |
-
'value' => strtotime( '
|
85 |
)
|
86 |
-
), '
|
87 |
|
88 |
if ( count( $lockouts ) == 0 ) {
|
89 |
$data = array(
|
@@ -105,7 +107,7 @@ class Main extends Controller {
|
|
105 |
$lockout404ThisWeek = 0;
|
106 |
//time
|
107 |
$todayMidnight = strtotime( '-24 hours', current_time( 'timestamp' ) );
|
108 |
-
$firstThisWeek = strtotime( '
|
109 |
foreach ( $lockouts as $k => $log ) {
|
110 |
//the other as DESC, so first will be last lockout
|
111 |
if ( $k == 0 ) {
|
@@ -142,14 +144,9 @@ class Main extends Controller {
|
|
142 |
return;
|
143 |
}
|
144 |
|
145 |
-
$perPage =
|
146 |
-
|
147 |
-
|
148 |
-
if ( count( $logs ) ) {
|
149 |
-
foreach ( $logs as $log ) {
|
150 |
-
$log->delete();
|
151 |
-
}
|
152 |
-
} else {
|
153 |
wp_send_json_success( array(
|
154 |
'message' => __( "Your logs have been successfully deleted.", wp_defender()->domain )
|
155 |
) );
|
@@ -243,24 +240,17 @@ class Main extends Controller {
|
|
243 |
//if current user can logged in, and no blacklisted we don't need to check the ip
|
244 |
return;
|
245 |
}
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
if ( $ID && is_object( ( $model = IP_Model::findByID( $ID ) ) ) ) {
|
258 |
-
if ( $model->is_locked() ) {
|
259 |
-
$this->renderPartial( 'locked', array(
|
260 |
-
'message' => $model->lockout_message
|
261 |
-
) );
|
262 |
-
die;
|
263 |
-
}
|
264 |
}
|
265 |
}
|
266 |
}
|
@@ -302,6 +292,16 @@ class Main extends Controller {
|
|
302 |
* Handle the logic here
|
303 |
*/
|
304 |
private function handleIpAction() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
$ip = $this->getUserIp();
|
306 |
$settings = Settings::instance();
|
307 |
if ( $settings->report ) {
|
@@ -315,6 +315,7 @@ class Main extends Controller {
|
|
315 |
wp_clear_scheduled_hook( 'cleanUpOldLog' );
|
316 |
wp_schedule_event( time(), 'hourly', 'cleanUpOldLog' );
|
317 |
}
|
|
|
318 |
$this->add_action( 'cleanUpOldLog', 'cleanUpOldLog' );
|
319 |
|
320 |
if ( $settings->isWhitelist( $ip ) ) {
|
@@ -330,7 +331,7 @@ class Main extends Controller {
|
|
330 |
'54.197.28.242',
|
331 |
'54.221.174.186',
|
332 |
'54.236.233.244',
|
333 |
-
array_key_exists( 'SERVER_ADDR', $_SERVER ) ? $_SERVER['SERVER_ADDR'] : $_SERVER['LOCAL_ADDR']
|
334 |
) );
|
335 |
|
336 |
if ( in_array( $ip, $arr ) ) {
|
@@ -365,18 +366,13 @@ class Main extends Controller {
|
|
365 |
* cron for delete old log
|
366 |
*/
|
367 |
public function cleanUpOldLog() {
|
368 |
-
$
|
|
|
369 |
'date' => array(
|
370 |
'compare' => '<=',
|
371 |
-
'value' =>
|
372 |
),
|
373 |
-
),
|
374 |
-
|
375 |
-
if ( count( $logs ) ) {
|
376 |
-
foreach ( $logs as $log ) {
|
377 |
-
$log->delete();
|
378 |
-
}
|
379 |
-
}
|
380 |
}
|
381 |
|
382 |
/**
|
@@ -693,10 +689,14 @@ class Main extends Controller {
|
|
693 |
* Add submit admin page
|
694 |
*/
|
695 |
public function adminMenu() {
|
696 |
-
$cap
|
|
|
|
|
|
|
|
|
697 |
add_submenu_page( 'wp-defender', esc_html__( "IP Lockouts", wp_defender()->domain ), esc_html__( "IP Lockouts", wp_defender()->domain ), $cap, $this->slug, array(
|
698 |
&$this,
|
699 |
-
|
700 |
) );
|
701 |
}
|
702 |
|
@@ -785,6 +785,14 @@ class Main extends Controller {
|
|
785 |
}
|
786 |
}
|
787 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
788 |
private function _renderSettings() {
|
789 |
$this->render( 'settings', array(
|
790 |
'settings' => Settings::instance()
|
@@ -838,4 +846,71 @@ class Main extends Controller {
|
|
838 |
'email_search' => $this->email_search
|
839 |
) );
|
840 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
841 |
}
|
8 |
use Hammer\Helper\HTTP_Helper;
|
9 |
use Hammer\Helper\Log_Helper;
|
10 |
use Hammer\Helper\WP_Helper;
|
11 |
+
use WP_Defender\Behavior\Utils;
|
12 |
use WP_Defender\Controller;
|
13 |
use WP_Defender\Module\Audit\Component\Audit_API;
|
14 |
use WP_Defender\Module\IP_Lockout\Behavior\IP_Lockout;
|
15 |
use WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api;
|
16 |
use WP_Defender\Module\IP_Lockout\Component\Logs_Table;
|
17 |
use WP_Defender\Module\IP_Lockout\Model\IP_Model;
|
18 |
+
use WP_Defender\Module\IP_Lockout\Model\IP_Model_Legacy;
|
19 |
use WP_Defender\Module\IP_Lockout\Model\Log_Model;
|
20 |
+
use WP_Defender\Module\IP_Lockout\Model\Log_Model_Legacy;
|
21 |
use WP_Defender\Module\IP_Lockout\Model\Settings;
|
22 |
use WP_Defender\Vendor\Email_Search;
|
23 |
|
61 |
$this->add_ajax_action( 'lockoutIPAction', 'lockoutIPAction' );
|
62 |
$this->add_ajax_action( 'lockoutEmptyLogs', 'lockoutEmptyLogs' );
|
63 |
$this->add_ajax_action( 'lockoutSummaryData', 'lockoutSummaryData' );
|
64 |
+
$this->add_ajax_action( 'migrateData', 'movingDataToTable' );
|
65 |
|
66 |
$this->handleIpAction();
|
67 |
$this->handleUserSearch();
|
76 |
return;
|
77 |
}
|
78 |
|
|
|
|
|
79 |
$lockouts = Log_Model::findAll( array(
|
80 |
'type' => array(
|
81 |
Log_Model::LOCKOUT_404,
|
83 |
),
|
84 |
'date' => array(
|
85 |
'compare' => '>=',
|
86 |
+
'value' => strtotime( '-30 days', current_time( 'timestamp' ) )
|
87 |
)
|
88 |
+
), 'id', 'DESC' );
|
89 |
|
90 |
if ( count( $lockouts ) == 0 ) {
|
91 |
$data = array(
|
107 |
$lockout404ThisWeek = 0;
|
108 |
//time
|
109 |
$todayMidnight = strtotime( '-24 hours', current_time( 'timestamp' ) );
|
110 |
+
$firstThisWeek = strtotime( '-7 days', current_time( 'timestamp' ) );
|
111 |
foreach ( $lockouts as $k => $log ) {
|
112 |
//the other as DESC, so first will be last lockout
|
113 |
if ( $k == 0 ) {
|
144 |
return;
|
145 |
}
|
146 |
|
147 |
+
$perPage = 500;
|
148 |
+
$count = Log_Model::deleteAll( array(), '0,' . $perPage );
|
149 |
+
if ( $count == 0 ) {
|
|
|
|
|
|
|
|
|
|
|
150 |
wp_send_json_success( array(
|
151 |
'message' => __( "Your logs have been successfully deleted.", wp_defender()->domain )
|
152 |
) );
|
240 |
//if current user can logged in, and no blacklisted we don't need to check the ip
|
241 |
return;
|
242 |
}
|
243 |
+
|
244 |
+
$model = IP_Model::findOne( array(
|
245 |
+
'ip' => $ip
|
246 |
+
) );
|
247 |
+
if ( is_object( $model ) && $model->is_locked() ) {
|
248 |
+
header('HTTP/1.0 403 Forbidden');
|
249 |
+
header( 'Cache-Control: private' );
|
250 |
+
$this->renderPartial( 'locked', array(
|
251 |
+
'message' => $model->lockout_message
|
252 |
+
) );
|
253 |
+
die;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
}
|
255 |
}
|
256 |
}
|
292 |
* Handle the logic here
|
293 |
*/
|
294 |
private function handleIpAction() {
|
295 |
+
if ( get_site_option( 'defenderLockoutNeedUpdateLog' ) == 1 ) {
|
296 |
+
//we are migratng, so no record
|
297 |
+
return;
|
298 |
+
}
|
299 |
+
|
300 |
+
if ( ! Login_Protection_Api::checkIfTableExists() ) {
|
301 |
+
//no table logs, omething happen
|
302 |
+
return;
|
303 |
+
}
|
304 |
+
|
305 |
$ip = $this->getUserIp();
|
306 |
$settings = Settings::instance();
|
307 |
if ( $settings->report ) {
|
315 |
wp_clear_scheduled_hook( 'cleanUpOldLog' );
|
316 |
wp_schedule_event( time(), 'hourly', 'cleanUpOldLog' );
|
317 |
}
|
318 |
+
|
319 |
$this->add_action( 'cleanUpOldLog', 'cleanUpOldLog' );
|
320 |
|
321 |
if ( $settings->isWhitelist( $ip ) ) {
|
331 |
'54.197.28.242',
|
332 |
'54.221.174.186',
|
333 |
'54.236.233.244',
|
334 |
+
array_key_exists( 'SERVER_ADDR', $_SERVER ) ? $_SERVER['SERVER_ADDR'] : ( isset( $_SERVER['LOCAL_ADDR'] ) ? $_SERVER['LOCAL_ADDR'] : null )
|
335 |
) );
|
336 |
|
337 |
if ( in_array( $ip, $arr ) ) {
|
366 |
* cron for delete old log
|
367 |
*/
|
368 |
public function cleanUpOldLog() {
|
369 |
+
$timestamp = Utils::instance()->localToUtc( apply_filters( 'ip_lockout_logs_store_backward', '-' . Settings::instance()->storage_days . ' days' ) );
|
370 |
+
Log_Model::deleteAll( array(
|
371 |
'date' => array(
|
372 |
'compare' => '<=',
|
373 |
+
'value' => $timestamp
|
374 |
),
|
375 |
+
), '0,1000' );
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
}
|
377 |
|
378 |
/**
|
689 |
* Add submit admin page
|
690 |
*/
|
691 |
public function adminMenu() {
|
692 |
+
$cap = is_multisite() ? 'manage_network_options' : 'manage_options';
|
693 |
+
$action = "actionIndex";
|
694 |
+
if ( get_site_option( 'defenderLockoutNeedUpdateLog' ) == 1 ) {
|
695 |
+
$action = "actionMigration";
|
696 |
+
}
|
697 |
add_submenu_page( 'wp-defender', esc_html__( "IP Lockouts", wp_defender()->domain ), esc_html__( "IP Lockouts", wp_defender()->domain ), $cap, $this->slug, array(
|
698 |
&$this,
|
699 |
+
$action
|
700 |
) );
|
701 |
}
|
702 |
|
785 |
}
|
786 |
}
|
787 |
|
788 |
+
/**
|
789 |
+
* Show the updating screen
|
790 |
+
*/
|
791 |
+
public function actionMigration() {
|
792 |
+
$this->layout = null;
|
793 |
+
$this->render( 'migration' );
|
794 |
+
}
|
795 |
+
|
796 |
private function _renderSettings() {
|
797 |
$this->render( 'settings', array(
|
798 |
'settings' => Settings::instance()
|
846 |
'email_search' => $this->email_search
|
847 |
) );
|
848 |
}
|
849 |
+
|
850 |
+
public function movingDataToTable() {
|
851 |
+
if ( ! $this->checkPermission() ) {
|
852 |
+
return;
|
853 |
+
}
|
854 |
+
$totalItems = get_site_option( 'defenderLogsTotal' );
|
855 |
+
$params = array(
|
856 |
+
'date' => array(
|
857 |
+
'compare' => '>=',
|
858 |
+
'value' => strtotime( '-30 days' )
|
859 |
+
)
|
860 |
+
);
|
861 |
+
if ( $totalItems === false ) {
|
862 |
+
//get the total
|
863 |
+
$totalLogs = Log_Model_Legacy::count( $params );
|
864 |
+
$totalsIPs = IP_Model_Legacy::count();
|
865 |
+
//get the 200 items and import each time
|
866 |
+
update_site_option( 'defenderLogsTotal', $totalLogs + $totalsIPs );
|
867 |
+
//prevent timeout so we end here at the first time
|
868 |
+
wp_send_json_error( array(
|
869 |
+
'progress' => 0
|
870 |
+
) );
|
871 |
+
}
|
872 |
+
|
873 |
+
$logs = Log_Model_Legacy::findAll( $params, 'id', 'DESC', '0,50' );
|
874 |
+
$logs = array_filter( $logs );
|
875 |
+
$ips = IP_Model_Legacy::findAll( array(), 'id', 'DESC', '0,50' );
|
876 |
+
$ips = array_filter( $ips );
|
877 |
+
if ( is_array( $logs ) && count( $logs ) ) {
|
878 |
+
foreach ( $logs as $item ) {
|
879 |
+
$model = new Log_Model();
|
880 |
+
$data = $item->export();
|
881 |
+
unset( $data['id'] );
|
882 |
+
$model->import( $data );
|
883 |
+
$model->save();
|
884 |
+
$item->delete();
|
885 |
+
}
|
886 |
+
}
|
887 |
+
|
888 |
+
if ( is_array( $ips ) && count( $ips ) ) {
|
889 |
+
foreach ( $ips as $item ) {
|
890 |
+
$model = new IP_Model();
|
891 |
+
$data = $item->export();
|
892 |
+
unset( $data['id'] );
|
893 |
+
$model->import( $data );
|
894 |
+
$model->save();
|
895 |
+
$item->delete();
|
896 |
+
}
|
897 |
+
}
|
898 |
+
|
899 |
+
if ( empty( $logs ) && empty( $ips ) ) {
|
900 |
+
//all moved
|
901 |
+
delete_site_option( 'defenderLogsTotal' );
|
902 |
+
delete_site_option( 'defenderLogsMovedCount' );
|
903 |
+
delete_site_option( 'defenderLockoutNeedUpdateLog' );
|
904 |
+
wp_send_json_success( array(
|
905 |
+
'message' => __( "Thanks for your patience. All sets!", wp_defender()->domain )
|
906 |
+
) );
|
907 |
+
}
|
908 |
+
|
909 |
+
$count = get_site_option( 'defenderLogsMovedCount', 0 );
|
910 |
+
$count += 200;
|
911 |
+
update_site_option( 'defenderLogsMovedCount', $count );
|
912 |
+
wp_send_json_error( array(
|
913 |
+
'progress' => round( ( $count / $totalItems ) * 200, 2 ) > 100 ? 100 : round( ( $count / $totalItems ) * 200, 2 )
|
914 |
+
) );
|
915 |
+
}
|
916 |
}
|
app/module/ip-lockout/js/script.js
CHANGED
@@ -14,6 +14,27 @@ jQuery(function ($) {
|
|
14 |
Defender.showNotification('error', data.data.message);
|
15 |
}
|
16 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
//media uploader
|
18 |
var mediaUploader;
|
19 |
$('.file-picker').click(function () {
|
@@ -102,6 +123,13 @@ jQuery(function ($) {
|
|
102 |
var that = $(this);
|
103 |
cleaningLog(that);
|
104 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
|
106 |
function cleaningLog(button) {
|
107 |
$.ajax({
|
@@ -161,7 +189,10 @@ WDIP.formHandler = function () {
|
|
161 |
} else if (data.data != undefined && data.data.url != undefined) {
|
162 |
location.href = data.data.url;
|
163 |
} else {
|
164 |
-
that.find('.button')
|
|
|
|
|
|
|
165 |
jq('div.iplockout').trigger('form-submitted', [data, that])
|
166 |
}
|
167 |
}
|
@@ -186,6 +217,7 @@ WDIP.listenFilter = function () {
|
|
186 |
inputs.on('click', function () {
|
187 |
clearTimeout(typingTimer);
|
188 |
});
|
|
|
189 |
//user is "finished typing," do something
|
190 |
function doneTyping() {
|
191 |
//build query
|
14 |
Defender.showNotification('error', data.data.message);
|
15 |
}
|
16 |
});
|
17 |
+
setTimeout(function () {
|
18 |
+
if ($('#moving-data').size() > 0) {
|
19 |
+
$('#moving-data').submit();
|
20 |
+
}
|
21 |
+
}, 1000);
|
22 |
+
$('div.iplockout').on('form-submitted', function (e, data, form) {
|
23 |
+
if (form.attr('id') != 'moving-data') {
|
24 |
+
return;
|
25 |
+
}
|
26 |
+
if (data.success == true) {
|
27 |
+
location.reload();
|
28 |
+
Defender.showNotification('success', data.data.message);
|
29 |
+
} else {
|
30 |
+
var progress = data.data.progress;
|
31 |
+
$('.scan-progress-text span').text(progress + '%');
|
32 |
+
$('.scan-progress-bar span').css('width', progress + '%');
|
33 |
+
setTimeout(function () {
|
34 |
+
$('#moving-data').submit();
|
35 |
+
}, 1000);
|
36 |
+
}
|
37 |
+
});
|
38 |
//media uploader
|
39 |
var mediaUploader;
|
40 |
$('.file-picker').click(function () {
|
123 |
var that = $(this);
|
124 |
cleaningLog(that);
|
125 |
});
|
126 |
+
if ($('#defLockoutUpgrade').size() > 0) {
|
127 |
+
$('body').addClass('wpmud');
|
128 |
+
WDP.showOverlay("#defLockoutUpgrade", {
|
129 |
+
title: 'Updating...',
|
130 |
+
class: 'no-close wp-defender'
|
131 |
+
});
|
132 |
+
}
|
133 |
|
134 |
function cleaningLog(button) {
|
135 |
$.ajax({
|
189 |
} else if (data.data != undefined && data.data.url != undefined) {
|
190 |
location.href = data.data.url;
|
191 |
} else {
|
192 |
+
var buttons = that.find('.button');
|
193 |
+
if (buttons.size() > 0) {
|
194 |
+
buttons.removeAttr('disabled');
|
195 |
+
}
|
196 |
jq('div.iplockout').trigger('form-submitted', [data, that])
|
197 |
}
|
198 |
}
|
217 |
inputs.on('click', function () {
|
218 |
clearTimeout(typingTimer);
|
219 |
});
|
220 |
+
|
221 |
//user is "finished typing," do something
|
222 |
function doneTyping() {
|
223 |
//build query
|
app/module/ip-lockout/model/ip-model-legacy.php
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Author: Hoang Ngo
|
5 |
+
*/
|
6 |
+
|
7 |
+
namespace WP_Defender\Module\IP_Lockout\Model;
|
8 |
+
|
9 |
+
use Hammer\WP\Model;
|
10 |
+
use WP_Defender\Behavior\Utils;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Class IP_Model
|
14 |
+
* @package WP_Defender\Module\IP_Lockout\Model
|
15 |
+
* @deprecated 1.7
|
16 |
+
*/
|
17 |
+
class IP_Model_Legacy extends Model {
|
18 |
+
const STATUS_BLOCKED = 'blocked', STATUS_NORMAL = 'normal';
|
19 |
+
|
20 |
+
static $post_type = 'wd_ip_lockout';
|
21 |
+
|
22 |
+
public $id;
|
23 |
+
public $ip;
|
24 |
+
public $status;
|
25 |
+
public $lockout_message;
|
26 |
+
public $release_time;
|
27 |
+
public $lock_time;
|
28 |
+
public $lock_time_404;
|
29 |
+
public $attempt;
|
30 |
+
public $attempt_404;
|
31 |
+
|
32 |
+
protected static function maps() {
|
33 |
+
return array(
|
34 |
+
'id' => array(
|
35 |
+
'type' => 'wp',
|
36 |
+
'map' => 'ID'
|
37 |
+
),
|
38 |
+
'ip' => array(
|
39 |
+
'type' => 'meta',
|
40 |
+
'map' => 'ip'
|
41 |
+
),
|
42 |
+
'status' => array(
|
43 |
+
'type' => 'meta',
|
44 |
+
'map' => 'status'
|
45 |
+
),
|
46 |
+
'lockout_message' => array(
|
47 |
+
'type' => 'meta',
|
48 |
+
'map' => 'lockout_message'
|
49 |
+
),
|
50 |
+
'release_time' => array(
|
51 |
+
'type' => 'meta',
|
52 |
+
'map' => 'release_time'
|
53 |
+
),
|
54 |
+
'lock_time' => array(
|
55 |
+
'type' => 'meta',
|
56 |
+
'map' => 'lock_time'
|
57 |
+
),
|
58 |
+
'lock_time_404' => array(
|
59 |
+
'type' => 'meta',
|
60 |
+
'map' => 'lock_time_404'
|
61 |
+
),
|
62 |
+
'attempt' => array(
|
63 |
+
'type' => 'meta',
|
64 |
+
'map' => 'attempt'
|
65 |
+
),
|
66 |
+
);
|
67 |
+
}
|
68 |
+
|
69 |
+
|
70 |
+
/**
|
71 |
+
* @return bool
|
72 |
+
*/
|
73 |
+
public function is_locked() {
|
74 |
+
if ( $this->status == self::STATUS_BLOCKED ) {
|
75 |
+
if ( $this->release_time < time() ) {
|
76 |
+
//unlock it
|
77 |
+
$this->attempt = 0;
|
78 |
+
$this->status = self::STATUS_NORMAL;
|
79 |
+
$this->save();
|
80 |
+
|
81 |
+
return false;
|
82 |
+
} else {
|
83 |
+
return true;
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
return false;
|
88 |
+
}
|
89 |
+
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @return array
|
93 |
+
*/
|
94 |
+
public function events() {
|
95 |
+
$that = $this;
|
96 |
+
|
97 |
+
//becase we store all the logs in main blog, so in multisite we need to force to main when saving
|
98 |
+
return array(
|
99 |
+
self::EVENT_BEFORE_INSERT => array(
|
100 |
+
array(
|
101 |
+
function () use ( $that ) {
|
102 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
103 |
+
wp_defender()->global['oldBlog'] = get_current_blog_id();
|
104 |
+
switch_to_blog( 1 );
|
105 |
+
}
|
106 |
+
}
|
107 |
+
)
|
108 |
+
),
|
109 |
+
self::EVENT_BEFORE_UPDATE => array(
|
110 |
+
array(
|
111 |
+
function () use ( $that ) {
|
112 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
113 |
+
wp_defender()->global['oldBlog'] = get_current_blog_id();
|
114 |
+
switch_to_blog( 1 );
|
115 |
+
}
|
116 |
+
}
|
117 |
+
)
|
118 |
+
),
|
119 |
+
self::EVENT_AFTER_INSERT => array(
|
120 |
+
array(
|
121 |
+
function () use ( $that ) {
|
122 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
123 |
+
if ( isset( wp_defender()->global['oldBlog'] ) ) {
|
124 |
+
switch_to_blog( wp_defender()->global['oldBlog'] );
|
125 |
+
unset( wp_defender()->global['oldBlog'] );
|
126 |
+
}
|
127 |
+
}
|
128 |
+
}
|
129 |
+
)
|
130 |
+
),
|
131 |
+
self::EVENT_AFTER_UPDATE => array(
|
132 |
+
array(
|
133 |
+
function () use ( $that ) {
|
134 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
135 |
+
if ( isset( wp_defender()->global['oldBlog'] ) ) {
|
136 |
+
switch_to_blog( wp_defender()->global['oldBlog'] );
|
137 |
+
unset( wp_defender()->global['oldBlog'] );
|
138 |
+
}
|
139 |
+
}
|
140 |
+
}
|
141 |
+
)
|
142 |
+
),
|
143 |
+
self::EVENT_BEFORE_DELELTE => array(
|
144 |
+
array(
|
145 |
+
function () use ( $that ) {
|
146 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
147 |
+
wp_defender()->global['oldBlog'] = get_current_blog_id();
|
148 |
+
switch_to_blog( 1 );
|
149 |
+
}
|
150 |
+
}
|
151 |
+
)
|
152 |
+
),
|
153 |
+
self::EVENT_AFTER_DELETE => array(
|
154 |
+
array(
|
155 |
+
function () use ( $that ) {
|
156 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
157 |
+
if ( isset( wp_defender()->global['oldBlog'] ) ) {
|
158 |
+
switch_to_blog( wp_defender()->global['oldBlog'] );
|
159 |
+
unset( wp_defender()->global['oldBlog'] );
|
160 |
+
}
|
161 |
+
}
|
162 |
+
}
|
163 |
+
)
|
164 |
+
),
|
165 |
+
);
|
166 |
+
}
|
167 |
+
}
|
app/module/ip-lockout/model/ip-model.php
CHANGED
@@ -6,13 +6,12 @@
|
|
6 |
|
7 |
namespace WP_Defender\Module\IP_Lockout\Model;
|
8 |
|
9 |
-
use Hammer\
|
10 |
-
use WP_Defender\Behavior\Utils;
|
11 |
|
12 |
-
class IP_Model extends
|
13 |
const STATUS_BLOCKED = 'blocked', STATUS_NORMAL = 'normal';
|
14 |
|
15 |
-
static $
|
16 |
|
17 |
public $id;
|
18 |
public $ip;
|
@@ -24,44 +23,6 @@ class IP_Model extends Model {
|
|
24 |
public $attempt;
|
25 |
public $attempt_404;
|
26 |
|
27 |
-
protected static function maps() {
|
28 |
-
return array(
|
29 |
-
'id' => array(
|
30 |
-
'type' => 'wp',
|
31 |
-
'map' => 'ID'
|
32 |
-
),
|
33 |
-
'ip' => array(
|
34 |
-
'type' => 'meta',
|
35 |
-
'map' => 'ip'
|
36 |
-
),
|
37 |
-
'status' => array(
|
38 |
-
'type' => 'meta',
|
39 |
-
'map' => 'status'
|
40 |
-
),
|
41 |
-
'lockout_message' => array(
|
42 |
-
'type' => 'meta',
|
43 |
-
'map' => 'lockout_message'
|
44 |
-
),
|
45 |
-
'release_time' => array(
|
46 |
-
'type' => 'meta',
|
47 |
-
'map' => 'release_time'
|
48 |
-
),
|
49 |
-
'lock_time' => array(
|
50 |
-
'type' => 'meta',
|
51 |
-
'map' => 'lock_time'
|
52 |
-
),
|
53 |
-
'lock_time_404' => array(
|
54 |
-
'type' => 'meta',
|
55 |
-
'map' => 'lock_time_404'
|
56 |
-
),
|
57 |
-
'attempt' => array(
|
58 |
-
'type' => 'meta',
|
59 |
-
'map' => 'attempt'
|
60 |
-
),
|
61 |
-
);
|
62 |
-
}
|
63 |
-
|
64 |
-
|
65 |
/**
|
66 |
* @return bool
|
67 |
*/
|
@@ -81,82 +42,4 @@ class IP_Model extends Model {
|
|
81 |
|
82 |
return false;
|
83 |
}
|
84 |
-
|
85 |
-
|
86 |
-
/**
|
87 |
-
* @return array
|
88 |
-
*/
|
89 |
-
public function events() {
|
90 |
-
$that = $this;
|
91 |
-
|
92 |
-
//becase we store all the logs in main blog, so in multisite we need to force to main when saving
|
93 |
-
return array(
|
94 |
-
self::EVENT_BEFORE_INSERT => array(
|
95 |
-
array(
|
96 |
-
function () use ( $that ) {
|
97 |
-
if ( Utils::instance()->isActivatedSingle() == false ) {
|
98 |
-
wp_defender()->global['oldBlog'] = get_current_blog_id();
|
99 |
-
switch_to_blog( 1 );
|
100 |
-
}
|
101 |
-
}
|
102 |
-
)
|
103 |
-
),
|
104 |
-
self::EVENT_BEFORE_UPDATE => array(
|
105 |
-
array(
|
106 |
-
function () use ( $that ) {
|
107 |
-
if ( Utils::instance()->isActivatedSingle() == false ) {
|
108 |
-
wp_defender()->global['oldBlog'] = get_current_blog_id();
|
109 |
-
switch_to_blog( 1 );
|
110 |
-
}
|
111 |
-
}
|
112 |
-
)
|
113 |
-
),
|
114 |
-
self::EVENT_AFTER_INSERT => array(
|
115 |
-
array(
|
116 |
-
function () use ( $that ) {
|
117 |
-
if ( Utils::instance()->isActivatedSingle() == false ) {
|
118 |
-
if ( isset( wp_defender()->global['oldBlog'] ) ) {
|
119 |
-
switch_to_blog( wp_defender()->global['oldBlog'] );
|
120 |
-
unset( wp_defender()->global['oldBlog'] );
|
121 |
-
}
|
122 |
-
}
|
123 |
-
}
|
124 |
-
)
|
125 |
-
),
|
126 |
-
self::EVENT_AFTER_UPDATE => array(
|
127 |
-
array(
|
128 |
-
function () use ( $that ) {
|
129 |
-
if ( Utils::instance()->isActivatedSingle() == false ) {
|
130 |
-
if ( isset( wp_defender()->global['oldBlog'] ) ) {
|
131 |
-
switch_to_blog( wp_defender()->global['oldBlog'] );
|
132 |
-
unset( wp_defender()->global['oldBlog'] );
|
133 |
-
}
|
134 |
-
}
|
135 |
-
}
|
136 |
-
)
|
137 |
-
),
|
138 |
-
self::EVENT_BEFORE_DELELTE => array(
|
139 |
-
array(
|
140 |
-
function () use ( $that ) {
|
141 |
-
if ( Utils::instance()->isActivatedSingle() == false ) {
|
142 |
-
wp_defender()->global['oldBlog'] = get_current_blog_id();
|
143 |
-
switch_to_blog( 1 );
|
144 |
-
}
|
145 |
-
}
|
146 |
-
)
|
147 |
-
),
|
148 |
-
self::EVENT_AFTER_DELETE => array(
|
149 |
-
array(
|
150 |
-
function () use ( $that ) {
|
151 |
-
if ( Utils::instance()->isActivatedSingle() == false ) {
|
152 |
-
if ( isset( wp_defender()->global['oldBlog'] ) ) {
|
153 |
-
switch_to_blog( wp_defender()->global['oldBlog'] );
|
154 |
-
unset( wp_defender()->global['oldBlog'] );
|
155 |
-
}
|
156 |
-
}
|
157 |
-
}
|
158 |
-
)
|
159 |
-
),
|
160 |
-
);
|
161 |
-
}
|
162 |
}
|
6 |
|
7 |
namespace WP_Defender\Module\IP_Lockout\Model;
|
8 |
|
9 |
+
use Hammer\Base\DB_Model;
|
|
|
10 |
|
11 |
+
class IP_Model extends DB_Model {
|
12 |
const STATUS_BLOCKED = 'blocked', STATUS_NORMAL = 'normal';
|
13 |
|
14 |
+
protected static $tableName = 'defender_lockout';
|
15 |
|
16 |
public $id;
|
17 |
public $ip;
|
23 |
public $attempt;
|
24 |
public $attempt_404;
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
/**
|
27 |
* @return bool
|
28 |
*/
|
42 |
|
43 |
return false;
|
44 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
}
|
app/module/ip-lockout/model/log-model-legacy.php
ADDED
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Author: Hoang Ngo
|
5 |
+
*/
|
6 |
+
|
7 |
+
namespace WP_Defender\Module\IP_Lockout\Model;
|
8 |
+
|
9 |
+
use Hammer\Helper\WP_Helper;
|
10 |
+
use Hammer\WP\Model;
|
11 |
+
use WP_Defender\Behavior\Utils;
|
12 |
+
use WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api;
|
13 |
+
use WP_Defender\Module\IP_Lockout\Component\Logs_Table;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Class Log_Model_Legacy
|
17 |
+
* @package WP_Defender\Module\IP_Lockout\Model
|
18 |
+
* @deprecated 1.7
|
19 |
+
*/
|
20 |
+
class Log_Model_Legacy extends Model {
|
21 |
+
const AUTH_FAIL = 'auth_fail', AUTH_LOCK = 'auth_lock', ERROR_404 = '404_error', LOCKOUT_404 = '404_lockout', ERROR_404_IGNORE = '404_error_ignore';
|
22 |
+
static $post_type = 'wd_iplockout_log';
|
23 |
+
|
24 |
+
public $id;
|
25 |
+
public $log;
|
26 |
+
public $ip;
|
27 |
+
public $date;
|
28 |
+
public $user_agent;
|
29 |
+
public $type;
|
30 |
+
public $blog_id;
|
31 |
+
|
32 |
+
protected static function maps() {
|
33 |
+
return array(
|
34 |
+
'id' => array(
|
35 |
+
'type' => 'wp',
|
36 |
+
'map' => 'ID'
|
37 |
+
),
|
38 |
+
'log' => array(
|
39 |
+
'type' => 'meta',
|
40 |
+
'map' => 'log'
|
41 |
+
),
|
42 |
+
'ip' => array(
|
43 |
+
'type' => 'meta',
|
44 |
+
'map' => 'ip'
|
45 |
+
),
|
46 |
+
'date' => array(
|
47 |
+
'type' => 'meta',
|
48 |
+
'map' => 'date'
|
49 |
+
),
|
50 |
+
'type' => array(
|
51 |
+
'type' => 'meta',
|
52 |
+
'map' => 'type'
|
53 |
+
),
|
54 |
+
'user_agent' => array(
|
55 |
+
'type' => 'meta',
|
56 |
+
'map' => 'user_agent'
|
57 |
+
),
|
58 |
+
'blog_id' => array(
|
59 |
+
'type' => 'meta',
|
60 |
+
'map' => 'blog_id'
|
61 |
+
),
|
62 |
+
);
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* @return string
|
67 |
+
*/
|
68 |
+
public function get_ip() {
|
69 |
+
return esc_html( $this->ip );
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public function get_log_text( $format = false ) {
|
76 |
+
if ( ! $format ) {
|
77 |
+
return esc_html( $this->log );
|
78 |
+
} else {
|
79 |
+
$text = sprintf( __( "Request for file <span class='log-text-table' tooltip='%s'>%s</span> which doesn't exist", wp_defender()->domain ), esc_attr( $this->log ), pathinfo( $this->log, PATHINFO_BASENAME ) );
|
80 |
+
|
81 |
+
return $text;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
public function before_update() {
|
86 |
+
$this->blog_id = get_current_blog_id();
|
87 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
88 |
+
switch_to_blog( 1 );
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
public function before_insert() {
|
93 |
+
$this->blog_id = get_current_blog_id();
|
94 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
95 |
+
switch_to_blog( 1 );
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* @return string
|
101 |
+
*/
|
102 |
+
public function get_date() {
|
103 |
+
return Utils::instance()->formatDateTime( date( 'Y-m-d H:i:s', $this->date ) );
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @return mixed|null
|
108 |
+
*/
|
109 |
+
public function get_type() {
|
110 |
+
$types = array(
|
111 |
+
'auth_fail' => __( "Failed login attempts", wp_defender()->domain ),
|
112 |
+
'auth_lock' => __( "Login lockout", wp_defender()->domain ),
|
113 |
+
'404_error' => __( "404 error", wp_defender()->domain ),
|
114 |
+
'404_error_ignore' => __( "404 error", wp_defender()->domain ),
|
115 |
+
'404_lockout' => __( "404 lockout", wp_defender()->domain )
|
116 |
+
);
|
117 |
+
|
118 |
+
if ( isset( $types[ $this->type ] ) ) {
|
119 |
+
return $types[ $this->type ];
|
120 |
+
}
|
121 |
+
|
122 |
+
return null;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* @return array
|
127 |
+
*/
|
128 |
+
public function events() {
|
129 |
+
$that = $this;
|
130 |
+
|
131 |
+
return array(
|
132 |
+
self::EVENT_BEFORE_INSERT => array(
|
133 |
+
array(
|
134 |
+
function () use ( $that ) {
|
135 |
+
$that->before_insert();
|
136 |
+
}
|
137 |
+
)
|
138 |
+
),
|
139 |
+
self::EVENT_BEFORE_UPDATE => array(
|
140 |
+
array(
|
141 |
+
function () use ( $that ) {
|
142 |
+
$that->before_update();
|
143 |
+
}
|
144 |
+
)
|
145 |
+
),
|
146 |
+
self::EVENT_AFTER_INSERT => array(
|
147 |
+
array(
|
148 |
+
function () use ( $that ) {
|
149 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
150 |
+
switch_to_blog( $that->blog_id );
|
151 |
+
}
|
152 |
+
}
|
153 |
+
)
|
154 |
+
),
|
155 |
+
self::EVENT_AFTER_UPDATE => array(
|
156 |
+
array(
|
157 |
+
function () use ( $that ) {
|
158 |
+
if ( Utils::instance()->isActivatedSingle() == false ) {
|
159 |
+
switch_to_blog( $that->blog_id );
|
160 |
+
}
|
161 |
+
}
|
162 |
+
)
|
163 |
+
)
|
164 |
+
);
|
165 |
+
}
|
166 |
+
}
|
app/module/ip-lockout/model/log-model.php
CHANGED
@@ -6,15 +6,12 @@
|
|
6 |
|
7 |
namespace WP_Defender\Module\IP_Lockout\Model;
|
8 |
|
9 |
-
use Hammer\
|
10 |
-
use Hammer\WP\Model;
|
11 |
use WP_Defender\Behavior\Utils;
|
12 |
-
use WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api;
|
13 |
-
use WP_Defender\Module\IP_Lockout\Component\Logs_Table;
|
14 |
|
15 |
-
class Log_Model extends
|
16 |
const AUTH_FAIL = 'auth_fail', AUTH_LOCK = 'auth_lock', ERROR_404 = '404_error', LOCKOUT_404 = '404_lockout', ERROR_404_IGNORE = '404_error_ignore';
|
17 |
-
static $
|
18 |
|
19 |
public $id;
|
20 |
public $log;
|
@@ -24,39 +21,6 @@ class Log_Model extends Model {
|
|
24 |
public $type;
|
25 |
public $blog_id;
|
26 |
|
27 |
-
protected static function maps() {
|
28 |
-
return array(
|
29 |
-
'id' => array(
|
30 |
-
'type' => 'wp',
|
31 |
-
'map' => 'ID'
|
32 |
-
),
|
33 |
-
'log' => array(
|
34 |
-
'type' => 'meta',
|
35 |
-
'map' => 'log'
|
36 |
-
),
|
37 |
-
'ip' => array(
|
38 |
-
'type' => 'meta',
|
39 |
-
'map' => 'ip'
|
40 |
-
),
|
41 |
-
'date' => array(
|
42 |
-
'type' => 'meta',
|
43 |
-
'map' => 'date'
|
44 |
-
),
|
45 |
-
'type' => array(
|
46 |
-
'type' => 'meta',
|
47 |
-
'map' => 'type'
|
48 |
-
),
|
49 |
-
'user_agent' => array(
|
50 |
-
'type' => 'meta',
|
51 |
-
'map' => 'user_agent'
|
52 |
-
),
|
53 |
-
'blog_id' => array(
|
54 |
-
'type' => 'meta',
|
55 |
-
'map' => 'blog_id'
|
56 |
-
),
|
57 |
-
);
|
58 |
-
}
|
59 |
-
|
60 |
/**
|
61 |
* @return string
|
62 |
*/
|
@@ -83,9 +47,6 @@ class Log_Model extends Model {
|
|
83 |
|
84 |
public function before_insert() {
|
85 |
$this->blog_id = get_current_blog_id();
|
86 |
-
//update cache total
|
87 |
-
$cache = WP_Helper::getCache();
|
88 |
-
$cache->increase( Login_Protection_Api::COUNT_TOTAL, 1 );
|
89 |
}
|
90 |
|
91 |
/**
|
6 |
|
7 |
namespace WP_Defender\Module\IP_Lockout\Model;
|
8 |
|
9 |
+
use Hammer\Base\DB_Model;
|
|
|
10 |
use WP_Defender\Behavior\Utils;
|
|
|
|
|
11 |
|
12 |
+
class Log_Model extends DB_Model {
|
13 |
const AUTH_FAIL = 'auth_fail', AUTH_LOCK = 'auth_lock', ERROR_404 = '404_error', LOCKOUT_404 = '404_lockout', ERROR_404_IGNORE = '404_error_ignore';
|
14 |
+
protected static $tableName = 'defender_lockout_log';
|
15 |
|
16 |
public $id;
|
17 |
public $log;
|
21 |
public $type;
|
22 |
public $blog_id;
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
/**
|
25 |
* @return string
|
26 |
*/
|
47 |
|
48 |
public function before_insert() {
|
49 |
$this->blog_id = get_current_blog_id();
|
|
|
|
|
|
|
50 |
}
|
51 |
|
52 |
/**
|
app/module/ip-lockout/model/settings.php
CHANGED
@@ -302,7 +302,7 @@ class Settings extends \Hammer\WP\Settings {
|
|
302 |
} elseif ( stristr( $ip, '-' ) ) {
|
303 |
$ips = explode( '-', $ip );
|
304 |
foreach ( $ips as $ip ) {
|
305 |
-
if ( ! filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 )
|
306 |
return false;
|
307 |
}
|
308 |
}
|
302 |
} elseif ( stristr( $ip, '-' ) ) {
|
303 |
$ips = explode( '-', $ip );
|
304 |
foreach ( $ips as $ip ) {
|
305 |
+
if ( ! filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) && ! filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
|
306 |
return false;
|
307 |
}
|
308 |
}
|
app/module/ip-lockout/view/layouts/layout.php
CHANGED
@@ -18,7 +18,7 @@
|
|
18 |
<div class="clear"></div>
|
19 |
<span class="sub"><?php _e( "Lockouts in the past 24 hours", wp_defender()->domain ) ?></span>
|
20 |
<h6 class="lockoutThisMonth">.</h6>
|
21 |
-
<span class="sub"><?php _e( "Total lockouts
|
22 |
</div>
|
23 |
</div>
|
24 |
<div class="column is-5">
|
@@ -31,13 +31,13 @@
|
|
31 |
</li>
|
32 |
<li>
|
33 |
<div>
|
34 |
-
<span class="list-label"><?php _e( "Login lockouts
|
35 |
<span class="list-detail loginLockoutThisWeek">.</span>
|
36 |
</div>
|
37 |
</li>
|
38 |
<li>
|
39 |
<div>
|
40 |
-
<span class="list-label"><?php _e( "404 lockouts
|
41 |
<span class="list-detail lockout404ThisWeek">.</span>
|
42 |
</div>
|
43 |
</li>
|
18 |
<div class="clear"></div>
|
19 |
<span class="sub"><?php _e( "Lockouts in the past 24 hours", wp_defender()->domain ) ?></span>
|
20 |
<h6 class="lockoutThisMonth">.</h6>
|
21 |
+
<span class="sub"><?php _e( "Total lockouts in the past 30 days", wp_defender()->domain ) ?></span>
|
22 |
</div>
|
23 |
</div>
|
24 |
<div class="column is-5">
|
31 |
</li>
|
32 |
<li>
|
33 |
<div>
|
34 |
+
<span class="list-label"><?php _e( "Login lockouts in the past 7 days", wp_defender()->domain ) ?></span>
|
35 |
<span class="list-detail loginLockoutThisWeek">.</span>
|
36 |
</div>
|
37 |
</li>
|
38 |
<li>
|
39 |
<div>
|
40 |
+
<span class="list-label"><?php _e( "404 lockouts in the past 7 days", wp_defender()->domain ) ?></span>
|
41 |
<span class="list-detail lockout404ThisWeek">.</span>
|
42 |
</div>
|
43 |
</li>
|
app/module/ip-lockout/view/locked.php
CHANGED
@@ -1,77 +1,78 @@
|
|
1 |
<!DOCTYPE html>
|
2 |
<html lang="en">
|
3 |
<head>
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
</head>
|
66 |
<body>
|
67 |
<div class="wp-defender">
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
</div>
|
76 |
</body>
|
77 |
</html>
|
1 |
<!DOCTYPE html>
|
2 |
<html lang="en">
|
3 |
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
6 |
+
<meta http-equiv="Cache-control" content="max-age=0">
|
7 |
+
<title><?php esc_html_e( "WP Defender", wp_defender()->domain ) ?></title>
|
8 |
+
<link rel="stylesheet"
|
9 |
+
href="https://fonts.googleapis.com/css?family=Roboto+Condensed:400,700|Roboto:400,500,300,300italic">
|
10 |
+
<style type="text/css">
|
11 |
+
html, body {
|
12 |
+
margin: 0;
|
13 |
+
padding: 0;
|
14 |
|
15 |
+
min-width: 100%;
|
16 |
+
width: 100%;
|
17 |
+
max-width: 100%;
|
18 |
|
19 |
+
min-height: 100%;
|
20 |
+
height: 100%;
|
21 |
+
max-height: 100%;
|
22 |
+
}
|
23 |
|
24 |
+
.wp-defender {
|
25 |
+
height: 100%;
|
26 |
+
display: flex;
|
27 |
+
align-items: center;
|
28 |
+
font-family: Roboto;
|
29 |
+
color: #000;
|
30 |
+
font-size: 13px;
|
31 |
+
line-height: 18px;
|
32 |
+
}
|
33 |
|
34 |
+
.container {
|
35 |
+
margin: 0 auto;
|
36 |
+
text-align: center;
|
37 |
+
}
|
38 |
|
39 |
+
.image {
|
40 |
+
width: 128px;
|
41 |
+
height: 128px;
|
42 |
+
background-color: #F2F2F2;
|
43 |
+
margin: 0 auto;
|
44 |
+
border-radius: 50%;
|
45 |
+
background-image: url("<?php echo wp_defender()->getPluginUrl().'assets/img/def-stand.svg' ?>");
|
46 |
+
background-repeat: no-repeat;
|
47 |
+
background-size: contain;
|
48 |
+
margin-bottom: 30px;
|
49 |
+
}
|
50 |
|
51 |
+
.powered {
|
52 |
+
position: absolute;
|
53 |
+
bottom: 20px;
|
54 |
+
display: block;
|
55 |
+
text-align: center;
|
56 |
+
width: 100%;
|
57 |
+
font-size: 10px;
|
58 |
+
color: #C0C0C0;
|
59 |
+
}
|
60 |
|
61 |
+
.powered strong {
|
62 |
+
color: #8A8A8A;
|
63 |
+
font-weight: normal;
|
64 |
+
}
|
65 |
+
</style>
|
66 |
</head>
|
67 |
<body>
|
68 |
<div class="wp-defender">
|
69 |
+
<div class="container">
|
70 |
+
<div class="image">
|
71 |
+
</div>
|
72 |
+
<p><?php echo $message ?></p>
|
73 |
+
</div>
|
74 |
+
<div class="powered"><?php esc_html_e( "Powered by", wp_defender()->domain ) ?>
|
75 |
+
<strong><?php esc_html_e( "Defender", wp_defender()->domain ) ?></strong></div>
|
76 |
</div>
|
77 |
</body>
|
78 |
</html>
|
app/module/ip-lockout/view/migration.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
<div id="wp-defender" class="wp-defender">
|
3 |
+
<div class="iplockout">
|
4 |
+
<div class="advanced-tools">
|
5 |
+
<h2 class="title">
|
6 |
+
<?php _e( "Migration", wp_defender()->domain ) ?>
|
7 |
+
</h2>
|
8 |
+
</div>
|
9 |
+
</div>
|
10 |
+
</div>
|
11 |
+
</div>
|
12 |
+
|
13 |
+
<dialog id="defLockoutUpgrade">
|
14 |
+
<div class="line">
|
15 |
+
<?php _e( "Please hold on, we are updating your data, please don't close this tab...", wp_defender()->domain ) ?>
|
16 |
+
</div>
|
17 |
+
<div class="well mline">
|
18 |
+
<div class="scan-progress">
|
19 |
+
<div class="scan-progress-text">
|
20 |
+
<img src="<?php echo wp_defender()->getPluginUrl() ?>assets/img/loading.gif" width="18"
|
21 |
+
height="18"/>
|
22 |
+
<span>0%</span>
|
23 |
+
</div>
|
24 |
+
<div class="scan-progress-bar">
|
25 |
+
<span style="width: 0%"></span>
|
26 |
+
</div>
|
27 |
+
</div>
|
28 |
+
</div>
|
29 |
+
<form method="post" id="moving-data" class="ip-frm">
|
30 |
+
<input type="hidden" name="action" value="migrateData"/>
|
31 |
+
<?php
|
32 |
+
wp_nonce_field( 'processScan' );
|
33 |
+
?>
|
34 |
+
</form>
|
35 |
+
</dialog>
|
app/module/ip-lockout/view/notification/report-free.php
CHANGED
@@ -76,7 +76,7 @@
|
|
76 |
</form>
|
77 |
<div class="presale-text">
|
78 |
<div>
|
79 |
-
<?php printf( __( "Schedule automated file scanning and email reporting for all your websites. This feature is included in a WPMU DEV membership along with 100+ plugins & themes, 24/7 support and lots of handy site management tools – <a href=\"%s\">Try it all FREE today!</a>", wp_defender()->domain ), "https://premium.wpmudev.org/project/wp-defender
|
80 |
</div>
|
81 |
</div>
|
82 |
</div>
|
76 |
</form>
|
77 |
<div class="presale-text">
|
78 |
<div>
|
79 |
+
<?php printf( __( "Schedule automated file scanning and email reporting for all your websites. This feature is included in a WPMU DEV membership along with 100+ plugins & themes, 24/7 support and lots of handy site management tools – <a href=\"%s\">Try it all FREE today!</a>", wp_defender()->domain ), "https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade" ) ?>
|
80 |
</div>
|
81 |
</div>
|
82 |
</div>
|
app/module/ip-lockout/view/pro-feature.php
CHANGED
@@ -32,7 +32,7 @@
|
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="tc">
|
35 |
-
<a class="button button-green mline" href="https://premium.wpmudev.org/project/wp-defender
|
36 |
<p class="is-marginless"><?php _e( "As part part of a WPMU DEV free trial.", wp_defender()->domain ) ?></p>
|
37 |
</div>
|
38 |
</div>
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="tc">
|
35 |
+
<a class="button button-green mline" href="https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade"><?php _e( "Get Defender Pro for Free", wp_defender()->domain ) ?></a>
|
36 |
<p class="is-marginless"><?php _e( "As part part of a WPMU DEV free trial.", wp_defender()->domain ) ?></p>
|
37 |
</div>
|
38 |
</div>
|
app/module/scan/behavior/core-result.php
CHANGED
@@ -70,14 +70,20 @@ class Core_Result extends Behavior {
|
|
70 |
//remove the file first
|
71 |
$raw = $this->getRaw();
|
72 |
if ( $raw['type'] == 'unknown' ) {
|
73 |
-
|
|
|
|
|
|
|
74 |
$this->getOwner()->delete();
|
75 |
|
76 |
return true;
|
77 |
} elseif ( $raw['type'] == 'modified' ) {
|
78 |
return new \WP_Error( Error_Code::INVALID, __( "This file can't not remove", wp_defender()->domain ) );
|
79 |
} elseif ( $raw['type'] == 'dir' ) {
|
80 |
-
$this->deleteFolder( $raw['file'] );
|
|
|
|
|
|
|
81 |
$this->getOwner()->delete();
|
82 |
|
83 |
return true;
|
@@ -90,7 +96,7 @@ class Core_Result extends Behavior {
|
|
90 |
*/
|
91 |
public function resolve() {
|
92 |
$originSrc = $this->getOriginalSource();
|
93 |
-
$raw
|
94 |
if ( $raw['type'] != 'modified' ) {
|
95 |
return new \WP_Error( Error_Code::INVALID, __( "This file is not resolvable", wp_defender()->domain ) );
|
96 |
}
|
@@ -391,11 +397,19 @@ class Core_Result extends Behavior {
|
|
391 |
\RecursiveIteratorIterator::CHILD_FIRST );
|
392 |
foreach ( $files as $file ) {
|
393 |
if ( $file->isDir() ) {
|
394 |
-
@rmdir( $file->getRealPath() );
|
395 |
} else {
|
396 |
-
@unlink( $file->getRealPath() );
|
|
|
|
|
|
|
397 |
}
|
398 |
}
|
399 |
-
@rmdir( $dir );
|
|
|
|
|
|
|
|
|
|
|
400 |
}
|
401 |
}
|
70 |
//remove the file first
|
71 |
$raw = $this->getRaw();
|
72 |
if ( $raw['type'] == 'unknown' ) {
|
73 |
+
$res = unlink( $raw['file'] );
|
74 |
+
if ( $res == false ) {
|
75 |
+
return new \WP_Error( Error_Code::NOT_WRITEABLE, __( "Defender doesn't have enough permission to remove this file", wp_defender()->domain ) );
|
76 |
+
}
|
77 |
$this->getOwner()->delete();
|
78 |
|
79 |
return true;
|
80 |
} elseif ( $raw['type'] == 'modified' ) {
|
81 |
return new \WP_Error( Error_Code::INVALID, __( "This file can't not remove", wp_defender()->domain ) );
|
82 |
} elseif ( $raw['type'] == 'dir' ) {
|
83 |
+
$res = $this->deleteFolder( $raw['file'] );
|
84 |
+
if ( is_wp_error( $res ) ) {
|
85 |
+
return $res;
|
86 |
+
}
|
87 |
$this->getOwner()->delete();
|
88 |
|
89 |
return true;
|
96 |
*/
|
97 |
public function resolve() {
|
98 |
$originSrc = $this->getOriginalSource();
|
99 |
+
$raw = $this->getRaw();
|
100 |
if ( $raw['type'] != 'modified' ) {
|
101 |
return new \WP_Error( Error_Code::INVALID, __( "This file is not resolvable", wp_defender()->domain ) );
|
102 |
}
|
397 |
\RecursiveIteratorIterator::CHILD_FIRST );
|
398 |
foreach ( $files as $file ) {
|
399 |
if ( $file->isDir() ) {
|
400 |
+
$res = @rmdir( $file->getRealPath() );
|
401 |
} else {
|
402 |
+
$res = @unlink( $file->getRealPath() );
|
403 |
+
}
|
404 |
+
if ( $res == false ) {
|
405 |
+
return new \WP_Error( Error_Code::NOT_WRITEABLE, __( "Defender doesn't have enough permission to remove this file", wp_defender()->domain ) );
|
406 |
}
|
407 |
}
|
408 |
+
$res = @rmdir( $dir );
|
409 |
+
if ( $res == false ) {
|
410 |
+
return new \WP_Error( Error_Code::NOT_WRITEABLE, __( "Defender doesn't have enough permission to remove this file", wp_defender()->domain ) );
|
411 |
+
}
|
412 |
+
|
413 |
+
return true;
|
414 |
}
|
415 |
}
|
app/module/scan/component/scan-api.php
CHANGED
@@ -323,8 +323,16 @@ class Scan_Api extends Component {
|
|
323 |
if ( is_array( self::$ignoreList ) ) {
|
324 |
return self::$ignoreList;
|
325 |
}
|
326 |
-
|
327 |
-
$ids
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
328 |
if ( empty( $ids ) ) {
|
329 |
self::$ignoreList = array();
|
330 |
|
@@ -337,6 +345,7 @@ class Scan_Api extends Component {
|
|
337 |
|
338 |
self::$ignoreList = $ignoreList;
|
339 |
|
|
|
340 |
return $ignoreList;
|
341 |
}
|
342 |
|
@@ -364,10 +373,18 @@ class Scan_Api extends Component {
|
|
364 |
* @param $id
|
365 |
*/
|
366 |
public static function indexIgnore( $id ) {
|
367 |
-
$
|
368 |
-
$ids
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
369 |
$ids[] = $id;
|
370 |
-
|
371 |
}
|
372 |
|
373 |
/**
|
@@ -376,10 +393,18 @@ class Scan_Api extends Component {
|
|
376 |
* @param $id
|
377 |
*/
|
378 |
public static function unIndexIgnore( $id ) {
|
379 |
-
$
|
380 |
-
$ids
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
381 |
unset( $ids[ array_search( $id, $ids ) ] );
|
382 |
-
|
383 |
}
|
384 |
|
385 |
/**
|
323 |
if ( is_array( self::$ignoreList ) ) {
|
324 |
return self::$ignoreList;
|
325 |
}
|
326 |
+
|
327 |
+
$ids = get_site_option( self::IGNORE_LIST );
|
328 |
+
if ( $ids == false ) {
|
329 |
+
$cache = Container::instance()->get( 'cache' );
|
330 |
+
$ids = $cache->get( self::IGNORE_LIST, array() );
|
331 |
+
update_site_option( self::IGNORE_LIST, $ids );
|
332 |
+
} elseif ( ! is_array( $ids ) ) {
|
333 |
+
$ids = unserialize( $ids );
|
334 |
+
}
|
335 |
+
|
336 |
if ( empty( $ids ) ) {
|
337 |
self::$ignoreList = array();
|
338 |
|
345 |
|
346 |
self::$ignoreList = $ignoreList;
|
347 |
|
348 |
+
|
349 |
return $ignoreList;
|
350 |
}
|
351 |
|
373 |
* @param $id
|
374 |
*/
|
375 |
public static function indexIgnore( $id ) {
|
376 |
+
$ids = get_site_option( self::IGNORE_LIST );
|
377 |
+
if ( $ids == false ) {
|
378 |
+
$cache = Container::instance()->get( 'cache' );
|
379 |
+
$ids = $cache->get( self::IGNORE_LIST, array() );
|
380 |
+
} elseif ( ! is_array( $ids ) ) {
|
381 |
+
$ids = unserialize( $ids );
|
382 |
+
}
|
383 |
+
if ( ! is_array( $ids ) ) {
|
384 |
+
$ids = array();
|
385 |
+
}
|
386 |
$ids[] = $id;
|
387 |
+
update_site_option( self::IGNORE_LIST, $ids );
|
388 |
}
|
389 |
|
390 |
/**
|
393 |
* @param $id
|
394 |
*/
|
395 |
public static function unIndexIgnore( $id ) {
|
396 |
+
$ids = get_site_option( self::IGNORE_LIST );
|
397 |
+
if ( $ids == false ) {
|
398 |
+
$cache = Container::instance()->get( 'cache' );
|
399 |
+
$ids = $cache->get( self::IGNORE_LIST, array() );
|
400 |
+
} elseif ( ! is_array( $ids ) ) {
|
401 |
+
$ids = unserialize( $ids );
|
402 |
+
}
|
403 |
+
if ( ! is_array( $ids ) ) {
|
404 |
+
$ids = array();
|
405 |
+
}
|
406 |
unset( $ids[ array_search( $id, $ids ) ] );
|
407 |
+
update_site_option( self::IGNORE_LIST, $ids );
|
408 |
}
|
409 |
|
410 |
/**
|
app/module/scan/controller/main.php
CHANGED
@@ -53,7 +53,6 @@ class Main extends \WP_Defender\Controller {
|
|
53 |
$this->add_ajax_action( 'ignoreItem', 'ignoreItem' );
|
54 |
$this->add_ajax_action( 'unIgnoreItem', 'unIgnoreItem' );
|
55 |
$this->add_ajax_action( 'deleteItem', 'deleteItem' );
|
56 |
-
$this->add_ajax_action( 'deleteItem', 'deleteItem' );
|
57 |
$this->add_ajax_action( 'resolveItem', 'resolveItem' );
|
58 |
$this->add_ajax_action( 'saveScanSettings', 'saveScanSettings' );
|
59 |
$this->add_ajax_action( 'scanBulkAction', 'scanBulkAction' );
|
53 |
$this->add_ajax_action( 'ignoreItem', 'ignoreItem' );
|
54 |
$this->add_ajax_action( 'unIgnoreItem', 'unIgnoreItem' );
|
55 |
$this->add_ajax_action( 'deleteItem', 'deleteItem' );
|
|
|
56 |
$this->add_ajax_action( 'resolveItem', 'resolveItem' );
|
57 |
$this->add_ajax_action( 'saveScanSettings', 'saveScanSettings' );
|
58 |
$this->add_ajax_action( 'scanBulkAction', 'scanBulkAction' );
|
app/module/scan/view/automation-free.php
CHANGED
@@ -60,7 +60,7 @@
|
|
60 |
</form>
|
61 |
<div class="presale-text">
|
62 |
<div>
|
63 |
-
<?php printf( __( "Schedule automated file scanning and email reporting for all your websites. This feature is included in a WPMU DEV membership along with 100+ plugins & themes, 24/7 support and lots of handy site management tools – <a href=\"%s\">Try it all FREE today!</a>", wp_defender()->domain ), "https://premium.wpmudev.org/project/wp-defender
|
64 |
</div>
|
65 |
</div>
|
66 |
</div>
|
60 |
</form>
|
61 |
<div class="presale-text">
|
62 |
<div>
|
63 |
+
<?php printf( __( "Schedule automated file scanning and email reporting for all your websites. This feature is included in a WPMU DEV membership along with 100+ plugins & themes, 24/7 support and lots of handy site management tools – <a href=\"%s\">Try it all FREE today!</a>", wp_defender()->domain ), "https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade" ) ?>
|
64 |
</div>
|
65 |
</div>
|
66 |
</div>
|
app/module/scan/view/pro-feature.php
CHANGED
@@ -32,7 +32,7 @@
|
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="tc">
|
35 |
-
<a class="button button-green mline" href="https://premium.wpmudev.org/project/wp-defender
|
36 |
<p class="is-marginless"><?php _e( "As part part of a WPMU DEV free trial.", wp_defender()->domain ) ?></p>
|
37 |
</div>
|
38 |
</div>
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="tc">
|
35 |
+
<a class="button button-green mline" href="https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade"><?php _e( "Get Defender Pro for Free", wp_defender()->domain ) ?></a>
|
36 |
<p class="is-marginless"><?php _e( "As part part of a WPMU DEV free trial.", wp_defender()->domain ) ?></p>
|
37 |
</div>
|
38 |
</div>
|
app/module/scan/view/setting-free.php
CHANGED
@@ -59,7 +59,7 @@
|
|
59 |
<div class="presale-text">
|
60 |
<div>
|
61 |
<?php printf( __( "Defenders scans through every line of code on your website, searching for anything suspicious. This feature is included when you join WPMU DEV, along with 100+ plugins and themes, 24/7 support and lots of handy site management tools. – <a href=\"%s\">Try it all FREE today!
|
62 |
-
</a>", wp_defender()->domain ), "https://premium.wpmudev.org/project/wp-defender
|
63 |
</div>
|
64 |
</div>
|
65 |
</div>
|
59 |
<div class="presale-text">
|
60 |
<div>
|
61 |
<?php printf( __( "Defenders scans through every line of code on your website, searching for anything suspicious. This feature is included when you join WPMU DEV, along with 100+ plugins and themes, 24/7 support and lots of handy site management tools. – <a href=\"%s\">Try it all FREE today!
|
62 |
+
</a>", wp_defender()->domain ), "https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade" ) ?>
|
63 |
</div>
|
64 |
</div>
|
65 |
</div>
|
app/view/pro-feature.php
CHANGED
@@ -32,7 +32,7 @@
|
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="tc">
|
35 |
-
<a class="button button-green mline" href="https://premium.wpmudev.org/project/wp-defender
|
36 |
<p class="is-marginless"><?php _e( "As part part of a WPMU DEV free trial.", wp_defender()->domain ) ?></p>
|
37 |
</div>
|
38 |
</div>
|
32 |
</p>
|
33 |
</div>
|
34 |
<div class="tc">
|
35 |
+
<a class="button button-green mline" href="https://premium.wpmudev.org/project/wp-defender/?utm_source=defender&utm_medium=plugin&utm_campaign=defender_modal_upgrade"><?php _e( "Get Defender Pro for Free", wp_defender()->domain ) ?></a>
|
36 |
<p class="is-marginless"><?php _e( "As part part of a WPMU DEV free trial.", wp_defender()->domain ) ?></p>
|
37 |
</div>
|
38 |
</div>
|
assets/css/defender-icon.css
CHANGED
@@ -1,3 +1,17 @@
|
|
1 |
#toplevel_page_wp-defender > ul > li.wp-first-item > a > span {
|
2 |
display: none;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
}
|
1 |
#toplevel_page_wp-defender > ul > li.wp-first-item > a > span {
|
2 |
display: none;
|
3 |
+
}
|
4 |
+
|
5 |
+
.def-oval {
|
6 |
+
-webkit-border-radius: 5px;
|
7 |
+
-moz-border-radius: 5px;
|
8 |
+
border-radius: 5px;
|
9 |
+
width: 10px;
|
10 |
+
height: 10px;
|
11 |
+
background-color: #E6E6E6;
|
12 |
+
display: block;
|
13 |
+
}
|
14 |
+
|
15 |
+
.def-oval.oval-green {
|
16 |
+
background-color: #1ABC9C;
|
17 |
}
|
assets/css/styles.css
CHANGED
@@ -2287,6 +2287,16 @@
|
|
2287 |
font-family: Roboto, sans-serif; }
|
2288 |
.wp-defender .wpmudev-register div label span {
|
2289 |
font-weight: 400; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2290 |
.wp-defender .toggle-row {
|
2291 |
display: none; }
|
2292 |
@media screen and (min-width: 769px) and (max-width: 979px) {
|
2287 |
font-family: Roboto, sans-serif; }
|
2288 |
.wp-defender .wpmudev-register div label span {
|
2289 |
font-weight: 400; }
|
2290 |
+
.wp-defender .advanced-tools .row > .col-third {
|
2291 |
+
width: 25%; }
|
2292 |
+
.wp-defender .advanced-tools .row > .col-two-third {
|
2293 |
+
width: 75%; }
|
2294 |
+
.wp-defender .advanced-tools i.icon-warning:not(.fill-red) {
|
2295 |
+
background: url("../img/wpmud-icon-warning-yellow.svg") no-repeat;
|
2296 |
+
mask: none;
|
2297 |
+
-webkit-mask: none; }
|
2298 |
+
.wp-defender .advanced-tools .toggle .toggle-label:after {
|
2299 |
+
left: 0; }
|
2300 |
.wp-defender .toggle-row {
|
2301 |
display: none; }
|
2302 |
@media screen and (min-width: 769px) and (max-width: 979px) {
|
assets/img/2factor-disabled.svg
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2 |
+
<svg width="128px" height="128px" viewBox="0 0 128 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
3 |
+
<!-- Generator: Sketch 45.1 (43504) - http://www.bohemiancoding.com/sketch -->
|
4 |
+
<title>graphic-defender-2factor-disabled</title>
|
5 |
+
<desc>Created with Sketch.</desc>
|
6 |
+
<defs>
|
7 |
+
<circle id="path-1" cx="64" cy="64" r="64"></circle>
|
8 |
+
<polygon id="path-3" points="0.327466846 0.3500558 3.88734603 0.3500558 3.88734603 21.3428699 0.327466846 21.3428699 0.327466846 0.3500558"></polygon>
|
9 |
+
<polygon id="path-5" points="51.1257801 0.184853857 51.1257801 49.0738103 0.330536413 49.0738103 0.330536413 0.184853857"></polygon>
|
10 |
+
</defs>
|
11 |
+
<g id="Security-Plugin" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
12 |
+
<g id="Advanced-Tools---2-Factor---Disabled" transform="translate(-726.000000, -223.000000)">
|
13 |
+
<g id="graphic-defender-2factor-disabled" transform="translate(726.000000, 223.000000)">
|
14 |
+
<mask id="mask-2" fill="white">
|
15 |
+
<use xlink:href="#path-1"></use>
|
16 |
+
</mask>
|
17 |
+
<use id="mask" fill="#333333" xlink:href="#path-1"></use>
|
18 |
+
<g id="graphic" mask="url(#mask-2)">
|
19 |
+
<g transform="translate(-6.000000, 10.000000)">
|
20 |
+
<path d="M39.4062404,173.10829 C44.5020972,174.081424 53.4377494,173.063861 54.0267519,168.804431 C53.575243,166.584784 53.2010742,166.272707 53.2010742,166.272707 C53.2010742,166.272707 66.6772379,143.156842 65.7953453,123.921688 C64.9134527,104.686534 45.3095141,107.332196 45.3095141,107.332196 C45.3095141,107.332196 37.373913,118.626064 34.904757,136.272889 C32.4359591,153.919715 37.417954,162.29669 37.417954,162.29669 C37.417954,162.29669 35.7354476,166.837383 34.6032737,173.249817 C34.7436317,172.456549 34.891867,171.690869 35.044399,170.959585 C35.3802558,171.617418 36.4050128,172.535016 39.4062404,173.10829" id="Fill-19" fill="#9F5622"></path>
|
21 |
+
<path d="M98.7215192,173.10829 C93.6256624,174.081424 84.6900102,173.063861 84.1006496,168.804431 C84.5525166,166.584784 84.9266854,166.272707 84.9266854,166.272707 C84.9266854,166.272707 71.4505217,143.156842 72.3324143,123.921688 C73.2143069,104.686534 92.8182455,107.332196 92.8182455,107.332196 C92.8182455,107.332196 100.753847,118.626064 103.223003,136.272889 C105.691801,153.919715 100.709806,162.29669 100.709806,162.29669 C100.709806,162.29669 102.392312,166.837383 103.524486,173.249817 C103.384128,172.456549 103.235893,171.690869 103.083361,170.959585 C102.747504,171.617418 101.722747,172.535016 98.7215192,173.10829" id="Fill-77" fill="#9F5622"></path>
|
22 |
+
<path d="M45.5730793,111.169696 C44.4412634,111.145332 43.5396777,111.197643 42.9821841,111.245655 C42.9291918,111.344187 42.8747673,111.447376 42.8207008,111.549132 C45.055688,112.721121 54.9878107,118.292633 62.1181432,128.225332 C63.6098056,130.696504 64.5615192,132.467564 65.1673504,133.735218 C65.5007008,131.627717 65.7244859,129.513409 65.8032583,127.424898 C60.5981944,123.105273 50.4301125,115.602542 45.5730793,111.169696" id="Fill-123" fill="#98480C"></path>
|
23 |
+
<path d="M95.3429003,111.617065 C95.2684246,111.475897 95.1939488,111.334728 95.1216215,111.200725 C91.5313913,110.649665 73.9902148,108.978569 72.3789616,128.537265 C72.495688,130.435162 72.7262762,132.348825 73.0445882,134.254963 C74.7668389,130.825706 78.878399,123.432255 86.114,117.877224 C91.3011611,113.894757 94.0055601,112.275973 95.3429003,111.617065" id="Fill-125" fill="#98480C"></path>
|
24 |
+
<path d="M100.613739,76.4418678 C106.021821,71.862837 111.178547,67.119348 111.178547,67.119348 L111.178547,70.2465609 C119.016399,59.9806461 122.406118,48.4047988 122.238905,47.40121 C122.0409,46.2105903 119.117013,44.801768 115.563662,39.7637592 C102.081412,32.6214743 69.0639693,25.4283113 69.0639693,25.4283113 C69.0639693,25.4283113 38.0946087,33.1162819 24.6123581,40.2589251 C19.0610537,41.4491865 16.0870384,46.2105903 15.8886752,47.40121 C15.7228951,48.3961997 19.056399,59.7882408 26.7553248,69.9896623 L28.2978312,69.1609222 L36.5098517,74.7177445 L31.6094936,75.5826725 C31.6728696,75.6457327 31.7355294,75.7095095 31.7996215,75.7722115 C34.3769105,77.9549545 35.7650946,78.1530925 35.7650946,78.1530925 C35.7650946,78.1530925 39.7799795,83.113351 42.1592634,84.5021087 C49.0983939,85.69237 69.0639693,85.2437827 69.0639693,85.2437827 C69.0639693,85.2437827 89.0291867,85.69237 95.9686752,84.5021087 C98.3479591,83.113351 102.362844,78.1530925 102.362844,78.1530925 C102.362844,78.1530925 102.51645,78.1298032 102.810414,78.0230308 C100.344123,78.2670308 98.7471918,78.0223142 100.613739,76.4418678" id="Fill-127" fill="#9F5622"></path>
|
25 |
+
<path d="M82.4067212,34.5627971 L69.0637545,31.4660394 L55.7211458,34.5627971 L55.499509,37.0296693 C55.499509,37.0296693 60.1549565,40.9662743 62.0845217,42.1733756 C64.014087,43.3804769 65.8169003,45.3865797 65.8169003,45.3865797 L66.623601,45.9931759 L69.0637545,45.9931759 L71.504266,45.9931759 L72.3109668,45.3865797 C72.3109668,45.3865797 74.1137801,43.3804769 76.0433453,42.1733756 C77.9729105,40.9662743 82.6283581,37.0296693 82.6283581,37.0296693 L82.4067212,34.5627971 Z" id="Fill-129" fill="#98480C"></path>
|
26 |
+
<path d="M68.0702916,21.3509674 C67.9360205,19.1470849 67.4053811,10.2917838 67.2954578,6.37237709 C67.2199079,3.67010396 67.526046,1.65253568 67.7824143,0.467290455 C66.6745882,0.59090279 64.8008798,0.851026138 61.97689,1.39993656 C56.8996522,2.38740206 54.2400102,7.87149016 54.2400102,10.2297985 C54.2400102,10.8908558 54.3234373,13.0567589 54.4491151,15.8432317 C54.0899847,16.1409762 53.6216471,16.6067618 53.5629258,17.0546326 C53.5396522,17.2334226 53.5503939,17.6859512 53.5840512,18.2839483 C54.0459437,18.8876781 54.4791918,19.419032 54.620624,19.4867501 C54.9657903,19.6515665 57.1918261,24.4624153 59.2427724,26.2796957 C60.7566343,27.6215166 62.5981176,28.5348147 63.6006752,28.9748029 C63.6364808,28.837217 63.6726445,28.6996311 63.7095243,28.5631201 C64.6053811,25.2481598 66.7372481,22.5136399 68.0702916,21.3509674" id="Fill-131" fill="#FF5B0C"></path>
|
27 |
+
<path d="M60.4257545,37.7939518 C61.9381841,38.0959959 62.4806394,33.2980458 63.6006394,28.9748388 C62.5980818,28.5348505 60.7565985,27.6215524 59.2427366,26.2797316 C57.1917903,24.4624511 54.9657545,19.6516023 54.6205882,19.4867859 C54.479156,19.4190678 54.0459079,18.8873557 53.5843734,18.2839841 C53.6896419,20.1528593 54.0201279,23.4516963 54.2399744,24.3241486 C54.4308184,25.0815877 54.7480563,25.5523894 54.943555,25.7877903 C55.1963427,30.4553204 55.4437596,34.4015994 55.5458056,34.6309093 C55.6782864,34.9297286 60.6420205,37.9225803 60.4257545,37.7939518" id="Fill-133" fill="#FFBC00"></path>
|
28 |
+
<path d="M70.0574322,21.3509674 C70.1917033,19.1470849 70.7223427,10.2917838 70.832266,6.37237709 C70.9078159,3.67010396 70.6016777,1.65253568 70.3453095,0.467290455 C71.4531355,0.59090279 73.326844,0.851026138 76.1508338,1.39993656 C81.2280716,2.38740206 83.8877136,7.87149016 83.8877136,10.2297985 C83.8877136,10.8908558 83.8042864,13.0567589 83.6786087,15.8432317 C84.0377391,16.1409762 84.5060767,16.6067618 84.564798,17.0546326 C84.5880716,17.2334226 84.5773299,17.6859512 84.5436726,18.2839483 C84.0817801,18.8876781 83.648532,19.419032 83.5070997,19.4867501 C83.1619335,19.6515665 80.9358977,24.4624153 78.8849514,26.2796957 C77.3710895,27.6215166 75.5296061,28.5348147 74.5270486,28.9748029 C74.491243,28.837217 74.4550793,28.6996311 74.4181995,28.5631201 C73.5223427,25.2481598 71.3904757,22.5136399 70.0574322,21.3509674" id="Fill-135" fill="#FF5B0C"></path>
|
29 |
+
<g id="Group-139" stroke-width="1" fill="none" transform="translate(66.956522, 0.008241)">
|
30 |
+
<mask id="mask-4" fill="white">
|
31 |
+
<use xlink:href="#path-3"></use>
|
32 |
+
</mask>
|
33 |
+
<g id="Clip-138"></g>
|
34 |
+
<path d="M3.38871611,0.459192952 C2.50431714,0.361019677 2.10723274,0.349912482 2.10723274,0.349912482 C2.10723274,0.349912482 1.71050639,0.361019677 0.826107417,0.459192952 C0.569381074,1.64443818 0.263601023,3.66200646 0.339150895,6.36392129 C0.449074169,10.2836863 0.979713555,19.1386291 1.1136266,21.3428699 C1.55976471,20.9537598 1.91638875,20.7405733 2.10723274,20.7405733 C2.29843478,20.7405733 2.65505882,20.9537598 3.10083887,21.3428699 C3.23510997,19.1386291 3.76574936,10.2836863 3.87567263,6.36392129 C3.95122251,3.66200646 3.6450844,1.64443818 3.38871611,0.459192952" id="Fill-137" fill="#FFBC00" mask="url(#mask-4)"></path>
|
35 |
+
</g>
|
36 |
+
<path d="M63.7094527,29.1566743 C64.6053095,25.841714 66.7371765,23.1071941 68.0702199,21.9445216 C68.5163581,21.5554115 68.8729821,21.342225 69.0638261,21.342225 C69.2546701,21.342225 69.6112941,21.5554115 70.0574322,21.9445216 C71.3904757,23.1071941 73.5223427,25.841714 74.4181995,29.1566743 C74.4550793,29.2931853 74.491243,29.4304129 74.5270486,29.5683571 C75.471601,33.2143836 76.0054629,37.1982837 77.0567161,38.1753586 C77.2002967,38.0908006 77.3413708,38.0080341 77.4860256,37.9224012 C77.5579949,37.8797639 77.6299642,37.8367683 77.7019335,37.7937727 C76.1895038,38.096175 75.6470486,33.2978667 74.5270486,28.9746596 C74.491243,28.8370737 74.4550793,28.6998461 74.4181995,28.5629768 C73.5223427,25.2480164 71.3904757,22.5134966 70.0574322,21.3508241 C69.6112941,20.9620722 69.2546701,20.7488858 69.0638261,20.7488858 C68.8729821,20.7488858 68.5163581,20.9620722 68.0702199,21.3508241 C66.7371765,22.5134966 64.6053095,25.2480164 63.7094527,28.5629768 C63.6725729,28.6998461 63.6364092,28.8370737 63.6006036,28.9746596 C62.4806036,33.2978667 61.9381483,38.096175 60.4257187,37.7937727 C60.497688,37.8367683 60.5696573,37.8797639 60.6419847,37.9224012 C60.7862813,38.0080341 60.9273555,38.0908006 61.0709361,38.1753586 C62.1221893,37.1982837 62.6560512,33.2143836 63.6006036,29.5683571 C63.6364092,29.4304129 63.6725729,29.2931853 63.7094527,29.1566743" id="Fill-140" fill="#98480C"></path>
|
37 |
+
<path d="M62.1412379,38.8049932 C62.167734,38.8204 62.1938721,38.8358068 62.2207263,38.8512135 C62.3263529,38.9128405 62.4305473,38.973751 62.5336675,39.0339448 C62.5648184,39.0518596 62.5959693,39.0701327 62.6267621,39.0880476 C62.7220051,39.1432253 62.8154578,39.1976863 62.9078363,39.2514308 C62.9414936,39.2707789 62.975867,39.2904852 63.0091662,39.3098332 C63.249422,39.4492106 63.4789361,39.5817803 63.6941279,39.7053927 C63.7188338,39.7197245 63.7424655,39.7329815 63.7668133,39.7469551 C63.8502404,39.7949668 63.9318772,39.8419037 64.0106496,39.8866907 C64.0378619,39.9024558 64.0647161,39.9175043 64.0912123,39.932911 C64.1606752,39.9723236 64.2272737,40.0103031 64.2920818,40.0475659 C64.3232327,40.0651225 64.3550997,40.0830373 64.3851765,40.1002355 C64.4507008,40.1374984 64.5126445,40.1726115 64.573156,40.2070079 C64.5928491,40.2181151 64.6146905,40.2306555 64.6340256,40.2414044 C64.713156,40.2861915 64.7876317,40.3277539 64.8563785,40.3664499 C64.8678363,40.3728993 64.8775038,40.3782737 64.8886036,40.3843648 C64.9430281,40.41482 64.9938721,40.4434837 65.0407775,40.4692811 C65.0608286,40.4803883 65.0787315,40.4904206 65.0973504,40.5004529 C65.1320818,40.5198009 65.1639488,40.5373574 65.1936675,40.5534808 C65.2108542,40.5627965 65.2273248,40.5717539 65.2427212,40.5799947 C65.2695754,40.5946849 65.2928491,40.6072253 65.3143325,40.6183325 C65.3250742,40.6240652 65.3372481,40.6305145 65.3469156,40.6355307 C65.3741279,40.6495043 65.3966854,40.6609698 65.4102916,40.6674191 C65.8940256,40.8866966 69.0638977,40.9963354 69.0638977,40.9963354 C69.0638977,40.9963354 72.2337698,40.8866966 72.7175038,40.6674191 C72.73111,40.6609698 72.7536675,40.6495043 72.7808798,40.6355307 C72.7905473,40.6305145 72.8027212,40.6240652 72.8134629,40.6183325 C72.8349463,40.6072253 72.8582199,40.5946849 72.8850742,40.5799947 C72.9004706,40.5717539 72.9169412,40.5627965 72.9341279,40.5534808 C72.9638465,40.5373574 72.9957136,40.5198009 73.030445,40.5004529 C73.0490639,40.4904206 73.0669668,40.4803883 73.0870179,40.4692811 C73.1339233,40.4434837 73.1847673,40.41482 73.2391918,40.3843648 C73.2502916,40.3782737 73.2599591,40.3728993 73.2714169,40.3664499 C73.3401637,40.3277539 73.4146394,40.2861915 73.4937698,40.2414044 C73.5131049,40.2306555 73.5345882,40.2181151 73.5546394,40.2070079 C73.6151509,40.1726115 73.6770946,40.1374984 73.7426189,40.1002355 C73.7726957,40.0830373 73.8045627,40.0651225 73.8357136,40.0475659 C73.9005217,40.0103031 73.9671202,39.9723236 74.0365831,39.932911 C74.0630793,39.9175043 74.0899335,39.9024558 74.1171458,39.8866907 C74.1959182,39.8419037 74.277555,39.7949668 74.3609821,39.7469551 C74.3853299,39.7329815 74.4089616,39.7197245 74.4336675,39.7053927 C74.6488593,39.5817803 74.8783734,39.4492106 75.1186292,39.3098332 C75.1519284,39.2904852 75.1863018,39.2707789 75.2199591,39.2514308 C75.3123376,39.1976863 75.4057903,39.1432253 75.5010332,39.0880476 C75.5318261,39.0701327 75.562977,39.0518596 75.5941279,39.0339448 C75.6972481,38.973751 75.8014425,38.9128405 75.9070691,38.8512135 C75.9339233,38.8358068 75.9600614,38.8204 75.9865575,38.8049932 C76.1265575,38.7229433 76.2687059,38.6401768 76.4119284,38.5559771 C76.6231816,38.4320065 76.8408798,38.3030197 77.0567877,38.1754661 C76.0055345,37.1983912 75.4716726,33.214491 74.5271202,29.5684646 C74.4913146,29.4305204 74.4551509,29.2932928 74.4182711,29.1567818 C73.5224143,25.8418214 71.3905473,23.1073016 70.0575038,21.9446291 C69.6113657,21.5555189 69.2547417,21.3423325 69.0638977,21.3423325 C68.8730537,21.3423325 68.5164297,21.5555189 68.0702916,21.9446291 C66.7372481,23.1073016 64.6053811,25.8418214 63.7095243,29.1567818 C63.6726445,29.2932928 63.6364808,29.4305204 63.6006752,29.5684646 C62.6561228,33.214491 62.1222609,37.1983912 61.0710077,38.1754661 C61.2869156,38.3030197 61.5046138,38.4320065 61.715867,38.5559771 C61.8590895,38.6401768 62.0012379,38.7229433 62.1412379,38.8049932" id="Fill-142" fill="#9F5622"></path>
|
38 |
+
<path d="M77.7019693,37.7939518 C76.1895396,38.0959959 75.6470844,33.2980458 74.5270844,28.9748388 C75.5296419,28.5348505 77.3711253,27.6215524 78.8849872,26.2797316 C80.9359335,24.4624511 83.1619693,19.6516023 83.5071355,19.4867859 C83.6485678,19.4190678 84.0818159,18.8873557 84.5433504,18.2839841 C84.4380818,20.1528593 84.1075959,23.4516963 83.8877494,24.3241486 C83.6969054,25.0815877 83.3796675,25.5523894 83.1841688,25.7877903 C82.9313811,30.4553204 82.6839642,34.4015994 82.5819182,34.6309093 C82.4494373,34.9297286 77.4857033,37.9225803 77.7019693,37.7939518" id="Fill-144" fill="#FFBC00"></path>
|
39 |
+
<path d="M69.0638619,21.8109128 C68.2421228,21.7654091 66.4196164,23.9409862 66.6924552,24.9556822 C67.0827366,25.1900082 69.2282097,25.7364106 69.9690281,25.7364106 C70.7102046,25.7364106 72.3092839,25.1423548 72.1921995,24.6196 C72.0751151,24.0968452 70.07,21.866807 69.0638619,21.8109128" id="Fill-146" fill="#98480C"></path>
|
40 |
+
<path d="M64.7448082,30.6150849 C64.6058824,31.069405 64.9764706,29.5201304 65.1325831,28.9748029 C65.2883376,28.4294755 67.8713555,27.6487471 69.9538107,27.6487471 C72.036266,27.6487471 73.3231202,26.9987971 73.7914578,28.0457398 C74.2594373,29.0926825 74.2984655,29.4832258 74.2984655,29.4832258 C74.2984655,29.4832258 73.442711,28.7806062 73.3829156,28.5853345 C73.3231202,28.3904211 72.9722251,28.8153609 70.4758568,29.0321304 C67.9798465,29.2488999 66.0295141,28.7763066 65.8343734,29.0321304 C65.6395908,29.2879542 64.864399,30.2248999 64.7448082,30.6150849" id="Fill-148" fill="#98480C"></path>
|
41 |
+
<path d="M69.5063836,31.2004341 C70.2028031,30.4981727 70.5533402,29.6393357 71.7431611,29.795553 C72.9333402,29.951412 73.7135448,31.9030537 73.0890946,31.7858907 C72.4653606,31.6687278 71.5598363,31.1613797 71.4080205,31.1613797 C71.2562046,31.1613797 69.5063836,31.2004341 69.5063836,31.2004341" id="Fill-150" fill="#98480C"></path>
|
42 |
+
<path d="M57.8664041,17.6369721 C57.6744859,17.2525198 63.2447673,17.2084493 63.8488082,17.2084493 C64.452491,17.2084493 66.2810844,16.8429868 66.3372992,17.4502996 C66.3935141,18.057254 64.961289,20.6258825 64.2179642,20.8125551 C63.4746394,20.9995859 59.2184246,20.3456946 57.8664041,17.6369721" id="Fill-152" fill="#1F191A"></path>
|
43 |
+
<path d="M80.294046,17.7116769 C80.4859642,17.3272247 75.1308747,17.0724758 74.5271918,17.0724758 C73.923509,17.0724758 71.8739949,16.8159354 71.8181381,17.4232482 C71.7619233,18.0302026 73.1937903,20.5988311 73.9374731,20.785862 C74.680798,20.9725345 78.9416675,20.4203994 80.294046,17.7116769" id="Fill-154" fill="#1F191A"></path>
|
44 |
+
<path d="M94.7082813,75.6808458 L100.201223,76.8281116 C100.313652,76.7091571 100.449355,76.5808869 100.613703,76.4418678 C106.021785,71.862837 111.178512,67.119348 111.178512,67.119348 L111.178512,70.2465609 C113.456465,67.263025 115.355954,64.1702085 116.904189,61.2568987 L113.182194,53.8505492 C113.182194,53.8505492 102.36424,53.9677122 100.094164,55.6234009 C97.824445,57.2787313 100.595801,60.469721 100.410685,62.0906549 C99.873243,66.7954479 98.0990742,68.495207 98.0990742,68.495207 C98.0990742,68.495207 99.141376,69.1168517 99.186133,71.0294391 C99.23089,72.9416681 97.5168747,73.5661791 94.7082813,75.6808458" id="Fill-156" fill="#98480C"></path>
|
45 |
+
<path d="M41.3225575,68.7320053 C40.1828645,67.469368 38.6013299,59.9103841 38.6013299,59.9103841 C38.3517647,55.955506 39.2884399,55.7545016 38.5798465,55.100252 C37.8712532,54.4456441 34.6555499,56.6817733 34.6555499,56.6817733 L28.4719182,69.2784076 L36.5099233,74.718067 L31.6095652,75.5826367 C31.6729412,75.6456969 31.735601,75.7094737 31.7996931,75.7721756 C32.8820972,76.6890567 33.7518159,77.2526573 34.4002558,77.6016382 C36.4322251,77.7782784 46.7392327,78.5643812 44.5751407,76.1523283 C42.1772379,73.4801521 41.0565217,70.5345956 41.3225575,68.7320053" id="Fill-158" fill="#98480C"></path>
|
46 |
+
<path d="M35.7649872,78.1532358 C35.7649872,78.1532358 40.873734,79.3065927 45.099156,79.6104282 C49.3249361,79.914622 55.3284655,73.2814767 69.0638619,73.2814767 L69.0638619,74.2209304 C69.0638619,74.2209304 58.0801279,76.5702814 48.5239642,81.1858584 C47.5575703,81.7383518 37.5058568,80.2886837 35.7649872,78.1532358" id="Fill-160" fill="#98480C"></path>
|
47 |
+
<path d="M39.5202097,79.7762479 C39.5202097,79.7762479 40.3763223,82.7332699 41.895555,83.1481774 C40.6248133,83.8113844 37.0517698,81.6279248 36.5096726,78.4494755 C39.503023,79.3061627 39.5202097,79.7762479 39.5202097,79.7762479" id="Fill-162" fill="#98480C"></path>
|
48 |
+
<path d="M66.0684706,45.7797028 C66.2947621,45.9380699 59.2184962,42.6288423 38.4469361,41.7442079 C35.2981893,41.9100993 37.1761944,40.6940405 39.2203376,40.1963665 C41.2644808,39.6986925 51.6499028,36.547832 52.9206445,35.884625 C54.1913862,35.2210596 55.9036113,34.9448129 54.578087,36.4926543 C53.2522046,38.0404957 45.6284706,40.4174355 44.523509,40.8043959 C43.4189054,41.1913562 61.0965013,42.2970596 66.0684706,45.7797028" id="Fill-164" fill="#98480C"></path>
|
49 |
+
<path d="M30.8233811,67.6705874 C36.5096726,68.1127254 57.8924348,69.0525374 67.1732532,66.399351 C64.5218465,68.0575477 60.2677801,69.3291424 50.0477801,69.3291424 C39.8277801,69.3291424 31.5412839,68.7762907 30.8233811,67.6705874" id="Fill-166" fill="#98480C"></path>
|
50 |
+
<path d="M102.362772,78.1532358 C102.362772,78.1532358 97.2540256,79.3065927 93.0286036,79.6104282 C88.8028235,79.914622 82.7992941,73.2814767 69.0638977,73.2814767 L69.0638977,74.2209304 C69.0638977,74.2209304 80.0476317,76.5702814 89.6037954,81.1858584 C90.5701893,81.7383518 100.621903,80.2886837 102.362772,78.1532358" id="Fill-168" fill="#98480C"></path>
|
51 |
+
<path d="M98.6075499,79.7762479 C98.6075499,79.7762479 97.7514373,82.7332699 96.2322046,83.1481774 C97.5029463,83.8113844 101.07599,81.6279248 101.618087,78.4494755 C98.6247366,79.3061627 98.6075499,79.7762479 98.6075499,79.7762479" id="Fill-170" fill="#98480C"></path>
|
52 |
+
<path d="M72.059289,45.7797028 C71.8329974,45.9380699 78.9092634,42.6288423 99.6808235,41.7442079 C102.829928,41.9100993 100.951565,40.6940405 98.907422,40.1963665 C96.8632788,39.6986925 86.4778568,36.547832 85.2071151,35.884625 C83.9363734,35.2210596 82.2241483,34.9448129 83.5496726,36.4926543 C84.875555,38.0404957 92.499289,40.4174355 93.6042506,40.8043959 C94.7088542,41.1913562 77.0312583,42.2970596 72.059289,45.7797028" id="Fill-172" fill="#98480C"></path>
|
53 |
+
<path d="M107.304414,67.6705874 C101.618123,68.1127254 80.2353606,69.0525374 70.9541841,66.399351 C73.6059488,68.0575477 77.8600153,69.3291424 88.0800153,69.3291424 C98.3000153,69.3291424 106.586153,68.7762907 107.304414,67.6705874" id="Fill-174" fill="#98480C"></path>
|
54 |
+
<path d="M69.2970997,45.2821363 C69.2970997,43.7894725 69.0640051,43.3473345 69.0640051,43.3473345 C69.0640051,43.3473345 68.8305524,43.7894725 68.8305524,45.2821363 C68.8305524,46.7748 68.1122916,62.6401744 68.0571509,63.3033815 C68.0020102,63.9669468 68.5788389,64.3539072 69.0640051,64.3539072 C69.5488133,64.3539072 70.1256419,63.9669468 70.0705013,63.3033815 C70.0153606,62.6401744 69.2970997,46.7748 69.2970997,45.2821363" id="Fill-176" fill="#98480C"></path>
|
55 |
+
<path d="M93.986046,104.143571 L69.0638977,104.143571 L44.1417494,104.143571 L42.3571969,111.286214 C55.8394476,115.253991 65.4145882,130.614526 65.4145882,130.614526 C65.4145882,130.614526 66.9416982,131.919442 69.0638977,131.919442 C71.1860972,131.919442 72.7132072,130.614526 72.7132072,130.614526 C72.7132072,130.614526 82.2883478,115.253991 95.7702404,111.286214 L93.986046,104.143571 Z" id="Fill-178" fill="#1F191A"></path>
|
56 |
+
<path d="M96.7585115,83.8684969 L95.9686394,84.5019653 C95.9686394,84.5019653 90.2730384,85.0311695 69.0639335,85.0311695 C47.8548286,85.0311695 42.1592276,84.5019653 42.1592276,84.5019653 L41.3693555,83.8684969 C41.3693555,83.8684969 40.0373862,84.4679272 40.4076164,86.8384176 C40.7015806,88.7241327 42.2261841,89.3593927 42.2261841,89.3593927 C42.2261841,89.3593927 42.8588696,98.5156628 42.7707877,99.2655777 C41.8455703,99.7062825 41.4048031,103.939199 44.1417852,104.143428 C52.4304297,104.480227 69.0639335,104.732826 69.0639335,104.732826 C69.0639335,104.732826 85.6970793,104.480227 93.9860818,104.143428 C96.7227059,103.939199 96.2822967,99.7062825 95.3567212,99.2655777 C95.2686394,98.5156628 95.9013248,89.3593927 95.9013248,89.3593927 C95.9013248,89.3593927 97.4259284,88.7241327 97.7202506,86.8384176 C98.0901228,84.4679272 96.7585115,83.8684969 96.7585115,83.8684969" id="Fill-180" fill="#FFBC00"></path>
|
57 |
+
<path d="M97.7202864,86.8382385 C98.0901586,84.4681063 96.7585473,83.8683178 96.7585473,83.8683178 L95.9686752,84.5017862 C95.9686752,84.5017862 90.2730742,85.0309903 69.0639693,85.0309903 C47.8548645,85.0309903 42.1592634,84.5017862 42.1592634,84.5017862 L41.3693913,83.8683178 C41.3693913,83.8683178 40.037422,84.4681063 40.4076522,86.8382385 C40.7016164,88.7239536 42.2262199,89.3595718 42.2262199,89.3595718 C42.2262199,89.3595718 42.4038159,91.9317833 42.5577801,94.4609991 C45.7312327,93.6591313 47.6615141,93.0145557 47.6615141,93.0145557 C47.6615141,93.0145557 53.1952737,93.8920241 54.7030486,93.7666203 C56.2111816,93.6412164 58.7168593,94.3932811 62.7260153,94.3932811 C66.7348133,94.3932811 68.5587519,92.3875366 68.5587519,92.3875366 C68.5587519,92.3875366 70.914046,92.2266614 70.9545064,90.8654925 C70.9759898,90.1331342 71.0651458,89.4874837 71.1761432,88.9102678 C71.0533299,90.2700035 71.8961944,89.7744793 72.5739949,90.3961239 C73.2528696,91.0188435 73.7000818,92.7748552 77.0260665,93.1779389 C80.3520512,93.5813809 83.7786496,91.7662502 85.0887775,91.6652106 C86.3989054,91.5645292 91.640133,92.1696922 92.696757,92.1696922 C92.9681637,92.1696922 94.0430486,92.4563295 95.6679079,92.8902267 C95.7903632,90.967607 95.9013606,89.3595718 95.9013606,89.3595718 C95.9013606,89.3595718 97.4259642,88.7239536 97.7202864,86.8382385" id="Fill-182" fill="#FF9000"></path>
|
58 |
+
<polygon id="Fill-184" fill="#98480C" points="70.36289 71.8627295 75.0011509 71.8627295 75.0011509 85.0161568 70.954399 85.0161568 70.0742967 78.0616194"></polygon>
|
59 |
+
<path d="M71.5167621,76.4331254 C71.5751253,74.6670814 69.7175294,74.374353 69.7483223,73.2815483 C69.7791151,72.1883853 71.3585013,72.839052 71.2346138,71.1969786 C71.1107263,69.5549051 68.8710844,67.5366203 67.1735396,67.8641034 C66.80689,67.4789345 66.6210588,66.1464294 66.2186036,65.7745175 C65.8161483,65.4029639 64.1440256,65.3409786 63.3079642,65.6817186 C62.4719028,66.0224587 62.1005985,66.6423119 60.7378363,66.983052 C59.3757903,67.3237921 58.7255601,67.2929786 57.9202916,68.3463706 C57.1153811,69.3997627 54.7930281,74.9770079 51.9446905,75.1317921 C49.0959949,75.2865762 48.2910844,75.1317921 42.841468,74.7290667 C37.3918517,74.3263413 32.716711,73.5689022 31.5089872,73.2815483 C30.3016215,72.9938361 29.3105217,72.4051548 29.3105217,72.4051548 C29.3105217,72.4051548 23.7735396,74.049378 19.9262251,79.3206379 C17.4305729,82.7402209 16.7538465,88.1261357 16.5855601,91.4901827 C11.0596777,90.9860593 8.00581586,89.5378244 6.5137954,88.647099 C8.57870588,89.8817891 13.6409054,92.1906526 24.138757,91.5664999 C36.7924655,90.8144352 47.6616215,87.1787994 47.6616215,87.1787994 C47.6616215,87.1787994 53.1953811,88.0562678 54.703156,87.930864 C56.211289,87.8054602 58.7169668,88.5578831 62.7257647,88.5578831 C66.7349207,88.5578831 68.5588593,86.5517803 68.5588593,86.5517803 C68.5588593,86.5517803 70.9141535,86.3909051 70.9542558,85.0297363 C70.9947161,83.6685674 71.2654066,82.5986937 71.4823887,81.7316159 C71.6990128,80.8638214 70.8321586,80.8018361 70.6151765,79.1285909 C70.3985524,77.455704 71.458399,78.1991695 71.5167621,76.4331254" id="Fill-192" fill="#FF5B0C"></path>
|
60 |
+
<path d="M18.2097391,67.119348 C18.2097391,67.119348 22.3531662,69.7255977 23.7144962,70.0810279 C25.0758261,70.4360999 29.3105575,72.4052981 29.3105575,72.4052981 C29.3105575,72.4052981 32.5617084,72.0025727 35.5342916,68.160558 C38.5068747,64.3185433 40.6741893,59.9806461 40.6741893,59.9806461 C40.6741893,59.9806461 40.9216061,61.3131512 41.7576675,63.0791953 C42.5937289,64.8452394 45.814087,67.8642467 45.814087,67.8642467 L48.4458005,51.4599941 L24.6125013,40.2589251 C24.6125013,40.2589251 15.0216061,40.4731865 11.3970026,53.8505492 C-0.254506394,61.8738855 3.60354987,65.5292276 2.24293606,69.1609222 C2.06140153,69.6446226 -0.416705882,78.6031131 0.460531969,83.2670602 C1.21209207,88.0564112 4.46932992,87.3039883 5.5968491,88.0564112 C4.99961125,67.1773921 18.2097391,67.119348 18.2097391,67.119348" id="Fill-196" fill="#9F5622"></path>
|
61 |
+
<path d="M19.9262609,79.3206737 C23.7735754,74.0494138 29.3105575,72.4051906 29.3105575,72.4051906 C29.3105575,72.4051906 25.0758261,70.4363507 23.7144962,70.0809204 C22.3531662,69.7254902 18.2097391,67.1192405 18.2097391,67.1192405 C18.2097391,67.1192405 4.99961125,67.1772846 5.5968491,88.0563037 C5.64053197,88.0853257 5.6910179,88.1193639 5.74544246,88.1562684 C5.76262916,88.1677339 5.78089003,88.179916 5.79879284,88.1920981 C5.82493095,88.2096546 5.85214322,88.2279278 5.88042967,88.2469175 C5.89833248,88.2587413 5.91766752,88.2712816 5.93628645,88.283822 C6.04119693,88.3529733 6.16042967,88.4303653 6.29577494,88.5145651 C6.30938107,88.5231642 6.32298721,88.531405 6.33730946,88.5400041 C6.38421483,88.5690261 6.43291049,88.5987648 6.48375448,88.62922 C6.49342199,88.635311 6.50380563,88.6414021 6.5138312,88.6471348 C8.00585166,89.5378602 11.0597136,90.9860952 16.5855959,91.4902185 C16.7538824,88.1261715 17.4306087,82.7402567 19.9262609,79.3206737" id="Fill-206" fill="#FFAD00"></path>
|
62 |
+
<path d="M120.61734,86.0000752 C120.437238,85.4146185 120.830384,82.7951119 120.109974,80.0928388 C118.219795,73.3371559 109.964092,71.469714 109.964092,71.469714 C108.012685,72.4600458 106.509207,72.8452147 104.303223,73.0150473 C102.097596,73.1845216 96.0457289,73.863852 91.973555,73.665714 C87.9013811,73.4675759 87.2507928,72.1092734 86.6571355,70.5248858 C86.0631202,68.9401398 84.5925831,66.5345363 83.5463427,65.9652029 C82.5001023,65.3958696 79.361023,64.1575965 78.2864962,63.3654026 C77.2119693,62.5728505 75.1474169,64.6670943 73.9880307,65.9652029 C72.9135038,65.6219548 71.3115601,66.4976317 70.4529412,67.864175 C69.5946803,69.2307184 71.5181586,71.1189416 71.5181586,71.1189416 C71.5181586,71.1189416 70.4529412,72.2224952 70.3684399,73.5524922 C70.2835806,74.8824893 71.6692583,75.2504599 71.7258312,76.12757 C71.7824041,77.0050385 70.6513043,77.4009562 70.5864962,78.701573 C70.522046,80.002548 71.8672634,80.3156993 71.838977,80.8581604 C71.8103325,81.4009797 71.3015345,81.7023072 71.1762148,83.0692088 C71.0508951,84.4361104 71.8955499,83.9380781 72.5740665,84.5604394 C73.2529412,85.1831589 73.7001535,86.9391706 77.0257801,87.3426126 C80.3517647,87.7460546 83.7787212,85.9305656 85.0888491,85.829526 C86.398977,85.7288446 91.6398465,86.3340076 92.6964706,86.3340076 C93.7534527,86.3340076 106.959284,90.6704717 117.541637,91.1749533 C118.268491,91.2097081 118.952737,91.2240399 119.604041,91.2236816 C120.32445,90.3411971 120.797442,86.5851736 120.61734,86.0000752" id="Fill-208" fill="#FF5B0C"></path>
|
63 |
+
<path d="M120.61734,86.0000752 C120.437238,85.4146185 120.830384,82.7951119 120.109974,80.0928388 C118.219795,73.3371559 109.964092,71.469714 109.964092,71.469714 C108.012685,72.4600458 106.509207,72.8452147 104.303223,73.0150473 C102.097596,73.1845216 96.0457289,73.863852 91.973555,73.665714 C87.9013811,73.4675759 87.2507928,72.1092734 86.6571355,70.5248858 C86.0631202,68.9401398 84.5925831,66.5345363 83.5463427,65.9652029 C82.5001023,65.3958696 79.361023,64.1575965 78.2864962,63.3654026 C77.2119693,62.5728505 75.1474169,64.6670943 73.9880307,65.9652029 C72.9135038,65.6219548 71.3115601,66.4976317 70.4529412,67.864175 C69.5946803,69.2307184 71.5181586,71.1189416 71.5181586,71.1189416 C71.5181586,71.1189416 70.4529412,72.2224952 70.3684399,73.5524922 C70.2835806,74.8824893 71.6692583,75.2504599 71.7258312,76.12757 C71.7824041,77.0050385 70.6513043,77.4009562 70.5864962,78.701573 C70.522046,80.002548 71.8672634,80.3156993 71.838977,80.8581604 C71.8103325,81.4009797 71.3015345,81.7023072 71.1762148,83.0692088 C71.0508951,84.4361104 71.8955499,83.9380781 72.5740665,84.5604394 C73.2529412,85.1831589 73.7001535,86.9391706 77.0257801,87.3426126 C80.3517647,87.7460546 83.7787212,85.9305656 85.0888491,85.829526 C86.398977,85.7288446 91.6398465,86.3340076 92.6964706,86.3340076 C93.7534527,86.3340076 106.959284,90.6704717 117.541637,91.1749533 C118.268491,91.2097081 118.952737,91.2240399 119.604041,91.2236816 C120.32445,90.3411971 120.797442,86.5851736 120.61734,86.0000752" id="Fill-210" fill="#FF5B0C"></path>
|
64 |
+
<g id="Group-222" stroke-width="1" fill="none" transform="translate(88.797954, 39.420869)">
|
65 |
+
<mask id="mask-6" fill="white">
|
66 |
+
<use xlink:href="#path-5"></use>
|
67 |
+
</mask>
|
68 |
+
<g id="Clip-221"></g>
|
69 |
+
<path d="M49.9089258,32.9952493 C48.1451407,26.1080717 47.9159847,22.6809645 46.842532,20.1868617 C44.3651407,14.4297515 37.9154731,12.160659 36.5043734,9.44584552 C33.7831458,2.68872952 26.765601,0.342961527 26.765601,0.342961527 C20.9217647,-1.75199883 0.178132992,17.6623037 0.331381074,17.7755254 C0.484987212,17.8887471 6.62565217,26.4061744 6.62565217,26.4061744 C6.62565217,26.4061744 8.32248082,24.5953433 9.11414322,22.4727941 C9.90616368,20.3506032 10.1270844,18.0868852 10.1270844,18.0868852 C10.1270844,18.0868852 10.1324552,17.945358 11.5177749,20.4355195 C12.9034527,22.9256811 16.952711,30.9454344 21.1659591,32.048988 C21.1659591,32.048988 24.7687212,30.7526708 24.9037084,30.7075254 C25.0386957,30.6627383 26.7938875,30.1220687 27.5314834,29.7168352 C28.2687212,29.3116018 31.8346036,27.4197956 31.8346036,27.4197956 C31.8346036,27.4197956 36.6157289,26.2273844 41.9167519,36.0672846 C44.8836061,41.574662 43.616087,47.3636605 43.1348593,49.0738103 C44.080844,48.7230379 45.016087,48.4432082 46.079156,48.3249703 C50.6146547,47.8204887 51.017468,44.39159 51.1184399,43.8462626 C51.2190537,43.3009351 50.2734271,34.4176869 49.9089258,32.9952493" id="Fill-220" fill="#9F5622" mask="url(#mask-6)"></path>
|
70 |
+
</g>
|
71 |
+
<path d="M130.714598,75.4880464 C125.413575,65.6481463 120.632808,66.8405574 120.632808,66.8405574 C120.632808,66.8405574 117.066926,68.7323636 116.32933,69.1375971 C115.592092,69.5428305 113.836542,70.0835001 113.701555,70.1286455 C113.566568,70.1734326 109.963806,71.4697498 109.963806,71.4697498 C109.963806,71.4697498 118.219867,73.3371918 120.110046,80.0928746 C120.830455,82.7951477 120.437309,85.4146543 120.617412,86.000111 C120.797514,86.5852094 120.324164,90.3412329 119.604113,91.2237175 C126.214189,91.2212094 129.120174,89.5393651 131.932706,88.4949304 C132.413934,86.7844223 133.681453,80.9954238 130.714598,75.4880464" id="Fill-223" fill="#FFAD00"></path>
|
72 |
+
<path d="M62.0177801,68.6410338 C61.1788542,68.6009046 61.4982404,69.1609222 61.4982404,69.1609222 C61.4982404,69.1609222 64.5349156,68.5210044 65.0941995,68.6808047 C65.5084706,68.7994009 66.930312,68.0688341 67.8462199,67.8491982 C67.6170639,67.8198179 67.3907724,67.822326 67.1734322,67.8642467 C67.1734322,67.8642467 62.8567059,68.6808047 62.0177801,68.6410338" id="Fill-225" fill="#E43500"></path>
|
73 |
+
<path d="M69.5144041,79.6354015 C70.5277033,79.9553604 70.9018721,80.1954191 70.9541483,80.2953838 C70.8130742,80.0137627 70.6827417,79.649375 70.6154271,79.12877 C70.398445,77.4558831 71.4582916,78.1993486 71.5166547,76.4329463 C71.5750179,74.6669022 70.3275499,74.3945968 70.3583427,73.3014338 C70.3894936,72.2082708 71.6419744,72.7611225 71.518087,71.119049 C71.4539949,70.2720358 70.5427417,69.4056746 69.7177801,68.7320769 C69.9938414,69.460494 70.5201841,71.0778449 70.074046,71.8392253 C69.4889821,72.8388728 69.4492379,73.0388023 69.5688286,73.4784323 C69.6887775,73.9180623 70.8979335,75.0294984 71.1668338,75.397469 C71.4360921,75.7657979 71.2423836,77.6937921 70.7253504,78.0449228 C70.2079591,78.3960535 68.5011049,79.3154426 69.5144041,79.6354015" id="Fill-227" fill="#E43500"></path>
|
74 |
+
<path d="M70.9543274,85.0296288 C70.9944297,83.6684599 71.2654783,82.5989445 71.4824604,81.7315084 C71.6317698,81.1338696 71.2669105,80.918175 70.9543274,80.2954555 C71.0066036,80.3954203 70.5676266,81.4344805 70.5676266,82.7537286 C70.5676266,84.0650943 71.0961176,85.0127888 70.6628696,85.7347565 C70.8322302,85.5452176 70.9460921,85.3151912 70.9543274,85.0296288" id="Fill-229" fill="#FF3500"></path>
|
75 |
+
<path d="M84.2314476,85.592262 C82.9130844,85.6721621 79.7167161,86.4718802 78.1985575,86.1519213 C76.680399,85.8319624 75.2023427,84.3127847 75.2023427,84.3127847 C75.2023427,84.3127847 73.0446957,84.2730138 72.8449003,84.1931137 C72.6451049,84.1132135 71.2698107,83.1135659 71.5183018,82.6338068 C71.7664348,82.1540476 72.4127263,81.7495307 72.1259233,81.3038097 C71.8387621,80.858447 71.6296573,79.7953809 71.5183018,79.2357216 C71.4065882,78.675704 71.6464859,78.1959448 71.7664348,77.5563853 C71.8860256,76.9168258 72.3257187,75.9573075 71.9261279,75.4374191 C71.5265371,74.917889 70.5279182,73.798212 70.5676624,73.3188112 C70.6077647,72.8386937 72.6053606,71.1998449 72.6053606,71.1998449 C72.6053606,71.1998449 71.1419847,70.0987994 70.2371765,68.7225821 C70.2873043,69.9071107 71.5183018,71.1188699 71.5183018,71.1188699 C71.5183018,71.1188699 70.4530844,72.2227818 70.3682251,73.5524206 C70.2833657,74.8824176 71.6694015,75.2503883 71.7256164,76.1274984 C71.7574834,76.6208728 71.4137494,76.9623295 71.0950793,77.3976599 C71.0027008,77.6964793 70.8788133,77.9404793 70.7255652,78.0447436 C70.6507315,78.2371489 70.5988133,78.4524852 70.5866394,78.7018596 C70.5221893,80.0024764 71.8670486,80.3156276 71.8387621,80.858447 C71.8104757,81.4009081 71.3016777,81.7025938 71.1763581,83.0691372 C71.0510384,84.4360388 71.895335,83.9380065 72.5742097,84.560726 C73.2527263,85.1830872 73.6999386,86.939099 77.0259233,87.342541 C80.3519079,87.745983 83.7785064,85.930494 85.0889923,85.8298126 C85.2007059,85.8212135 85.3428542,85.8179888 85.5064859,85.8187054 C85.2379437,85.6764617 84.8301176,85.556074 84.2314476,85.592262" id="Fill-231" fill="#E43500"></path>
|
76 |
+
<path d="M45.1709821,99.3815941 C46.4009054,99.526346 58.6414169,99.7434737 71.0423376,99.8158496 C83.4432583,99.8885838 93.7889361,99.5987219 93.7889361,99.5987219 C93.7889361,99.5987219 87.6393197,99.3815941 68.5395243,98.9473386 C49.4393708,98.5130831 45.1709821,99.3815941 45.1709821,99.3815941" id="Fill-233" fill="#F9D400"></path>
|
77 |
+
<path d="M44.4475294,89.2460634 C44.4475294,89.2460634 62.4208798,90.0425568 70.0743325,89.6803189 C77.7274271,89.3184394 93.4994476,89.2460634 93.4994476,89.2460634 C93.4994476,89.2460634 84.6303939,89.1736875 70.3629258,89.2460634 C56.0954578,89.3184394 44.4475294,89.2460634 44.4475294,89.2460634" id="Fill-235" fill="#FF7E00"></path>
|
78 |
+
<path d="M28.6531662,40.2588176 C26.7139335,40.2606091 26.462578,40.6927148 28.4719898,41.4390467 C30.4810435,42.1850203 35.3151611,47.8891025 40.4622199,48.6590819 C45.6092788,49.4294197 34.4056982,43.2129733 38.3457494,41.4630526 C44.1179744,38.8997985 32.8141381,41.1982714 32.2609412,41.0778837 C31.7077442,40.957496 29.5429361,40.258101 28.6531662,40.2588176" id="Fill-237" fill="#98480C"></path>
|
79 |
+
<path d="M100.438578,45.1806667 C101.692133,45.8399325 103.048092,44.966047 106.193616,42.8198502 C109.339499,40.6736535 111.877402,40.2085844 109.267887,39.4575947 C106.658373,38.7062467 105.292389,41.8047959 99.719601,40.4343113 C94.1471714,39.064185 95.2553555,40.3515448 95.2553555,40.3515448 C95.2553555,40.3515448 102.118578,42.3193098 101.153616,43.5353686 C100.188297,44.7514273 98.3292685,44.0717386 100.438578,45.1806667" id="Fill-239" fill="#98480C"></path>
|
80 |
+
</g>
|
81 |
+
</g>
|
82 |
+
</g>
|
83 |
+
</g>
|
84 |
+
</g>
|
85 |
+
</svg>
|
assets/img/android-download.svg
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2 |
+
<svg width="122px" height="40px" viewBox="0 0 122 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
3 |
+
<!-- Generator: Sketch 45.1 (43504) - http://www.bohemiancoding.com/sketch -->
|
4 |
+
<title>graphic-defender-download-android</title>
|
5 |
+
<desc>Created with Sketch.</desc>
|
6 |
+
<defs>
|
7 |
+
<path d="M17.2892223,9.4886212 L11.789266,6.30733698 C11.789266,6.30733698 1.76950676,0.510781483 1.18045284,0.170074664 C0.591418798,-0.170632155 0.00453103111,0.0357989049 0.00453103111,0.747794923 L0.00453103111,25.7515381 C0.00453103111,26.2852962 0.423989249,26.5153808 0.935757289,26.2195918 C1.44728685,25.923325 11.789266,19.940886 11.789266,19.940886 L17.2889839,16.7598208 C17.2889839,16.7598208 21.955469,14.0607068 22.5757234,13.7020607 C23.1960176,13.3429567 23.1363988,12.8507715 22.6129454,12.5683823 C22.0897306,12.2857143 17.2892223,9.4886212 17.2892223,9.4886212 L17.2892223,9.4886212 Z" id="path-1"></path>
|
8 |
+
<linearGradient x1="49.9998541%" y1="0.000147098194%" x2="49.9998541%" y2="100.000147%" id="linearGradient-3">
|
9 |
+
<stop stop-color="#257CB0" offset="0%"></stop>
|
10 |
+
<stop stop-color="#4A93B5" offset="28.6%"></stop>
|
11 |
+
<stop stop-color="#78BCBB" offset="76.7%"></stop>
|
12 |
+
<stop stop-color="#89CFBD" offset="100%"></stop>
|
13 |
+
</linearGradient>
|
14 |
+
<path d="M17.2892223,9.4886212 L11.789266,6.30733698 C11.789266,6.30733698 1.76950676,0.510781483 1.18045284,0.170074664 C0.591418798,-0.170632155 0.00453103111,0.0357989049 0.00453103111,0.747794923 L0.00453103111,25.7515381 C0.00453103111,26.2852962 0.423989249,26.5153808 0.935757289,26.2195918 C1.44728685,25.923325 11.789266,19.940886 11.789266,19.940886 L17.2889839,16.7598208 C17.2889839,16.7598208 21.955469,14.0607068 22.5757234,13.7020607 C23.1960176,13.3429567 23.1363988,12.8507715 22.6129454,12.5683823 C22.0897306,12.2857143 17.2892223,9.4886212 17.2892223,9.4886212 L17.2892223,9.4886212 Z" id="path-4"></path>
|
15 |
+
<linearGradient x1="0.00126473415%" y1="49.9985397%" x2="100.001265%" y2="49.9985397%" id="linearGradient-6">
|
16 |
+
<stop stop-color="#52C1AD" offset="0%"></stop>
|
17 |
+
<stop stop-color="#DEE89A" offset="100%"></stop>
|
18 |
+
</linearGradient>
|
19 |
+
<path d="M17.2892223,9.4886212 L11.789266,6.30733698 C11.789266,6.30733698 1.76950676,0.510781483 1.18045284,0.170074664 C0.591418798,-0.170632155 0.00453103111,0.0357989049 0.00453103111,0.747794923 L0.00453103111,25.7515381 C0.00453103111,26.2852962 0.423989249,26.5153808 0.935757289,26.2195918 C1.44728685,25.923325 11.789266,19.940886 11.789266,19.940886 L17.2889839,16.7598208 C17.2889839,16.7598208 21.955469,14.0607068 22.5757234,13.7020607 C23.1960176,13.3429567 23.1363988,12.8507715 22.6129454,12.5683823 C22.0897306,12.2857143 17.2892223,9.4886212 17.2892223,9.4886212 L17.2892223,9.4886212 Z" id="path-7"></path>
|
20 |
+
<linearGradient x1="49.999885%" y1="0.000292074841%" x2="49.999885%" y2="100.000292%" id="linearGradient-9">
|
21 |
+
<stop stop-color="#EC413D" offset="0%"></stop>
|
22 |
+
<stop stop-color="#DA4452" offset="16.7%"></stop>
|
23 |
+
<stop stop-color="#B0487A" offset="57.5%"></stop>
|
24 |
+
<stop stop-color="#954A92" offset="86.2%"></stop>
|
25 |
+
<stop stop-color="#8A4A9D" offset="100%"></stop>
|
26 |
+
</linearGradient>
|
27 |
+
<path d="M17.2892223,9.4886212 L11.789266,6.30733698 C11.789266,6.30733698 1.76950676,0.510781483 1.18045284,0.170074664 C0.591418798,-0.170632155 0.00453103111,0.0357989049 0.00453103111,0.747794923 L0.00453103111,25.7515381 C0.00453103111,26.2852962 0.423989249,26.5153808 0.935757289,26.2195918 C1.44728685,25.923325 11.789266,19.940886 11.789266,19.940886 L17.2889839,16.7598208 C17.2889839,16.7598208 21.955469,14.0607068 22.5757234,13.7020607 C23.1960176,13.3429567 23.1363988,12.8507715 22.6129454,12.5683823 C22.0897306,12.2857143 17.2892223,9.4886212 17.2892223,9.4886212 L17.2892223,9.4886212 Z" id="path-10"></path>
|
28 |
+
<linearGradient x1="50.0010991%" y1="0.000547669119%" x2="50.0010991%" y2="99.9972617%" id="linearGradient-12">
|
29 |
+
<stop stop-color="#F58879" offset="0%"></stop>
|
30 |
+
<stop stop-color="#F69079" offset="11.9%"></stop>
|
31 |
+
<stop stop-color="#FCB877" offset="71.3%"></stop>
|
32 |
+
<stop stop-color="#FEC874" offset="100%"></stop>
|
33 |
+
</linearGradient>
|
34 |
+
</defs>
|
35 |
+
<g id="Security-Plugin" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
36 |
+
<g id="Advanced-Tools---2-Factor---New" transform="translate(-822.000000, -978.000000)">
|
37 |
+
<g id="graphic-defender-download-android" transform="translate(822.000000, 978.000000)">
|
38 |
+
<g>
|
39 |
+
<path d="M121.992468,34.5883922 C121.992468,37.5716078 119.57884,39.9909607 116.601714,39.9909607 L5.40901776,39.9909607 C2.43165336,39.9911996 0.0170907314,37.5718467 0.0170907314,34.5883922 L0.0170907314,5.41829766 C0.0170907314,2.43532106 2.43165336,0.0162070682 5.40901776,0.0162070682 L116.601475,0.0162070682 C119.578601,0.0162070682 121.99223,2.43532106 121.99223,5.41829766 L121.99223,34.5883922 L121.992468,34.5883922 Z" id="Shape" fill="#000000" fill-rule="nonzero"></path>
|
40 |
+
<g id="Clipped" transform="translate(9.161427, 8.123444)">
|
41 |
+
<mask id="mask-2" fill="white">
|
42 |
+
<use xlink:href="#path-1"></use>
|
43 |
+
</mask>
|
44 |
+
<g id="a"></g>
|
45 |
+
<polygon id="Shape" fill="url(#linearGradient-3)" fill-rule="nonzero" mask="url(#mask-2)" points="0.00476950643 -0.411229467 0.00476950643 26.6596715 13.6298185 13.1243405"></polygon>
|
46 |
+
</g>
|
47 |
+
<g id="Clipped" transform="translate(9.161427, 8.123444)">
|
48 |
+
<mask id="mask-5" fill="white">
|
49 |
+
<use xlink:href="#path-4"></use>
|
50 |
+
</mask>
|
51 |
+
<g id="d"></g>
|
52 |
+
<polygon id="Shape" fill="url(#linearGradient-6)" fill-rule="nonzero" mask="url(#mask-5)" points="17.2892223 9.4886212 11.789266 6.30733698 0.00476950643 -0.509666501 0.00476950643 -0.411229467 13.6298185 13.1243405"></polygon>
|
53 |
+
</g>
|
54 |
+
<g id="Clipped" transform="translate(9.161427, 8.123444)">
|
55 |
+
<mask id="mask-8" fill="white">
|
56 |
+
<use xlink:href="#path-7"></use>
|
57 |
+
</mask>
|
58 |
+
<g id="g"></g>
|
59 |
+
<polygon id="Shape" fill="url(#linearGradient-9)" fill-rule="nonzero" mask="url(#mask-8)" points="0.00476950643 26.6596715 0.00476950643 26.7581085 11.789266 19.9408661 17.2889839 16.7595819 13.6298185 13.1243405"></polygon>
|
60 |
+
</g>
|
61 |
+
<g id="Clipped" transform="translate(9.161427, 8.123444)">
|
62 |
+
<mask id="mask-11" fill="white">
|
63 |
+
<use xlink:href="#path-10"></use>
|
64 |
+
</mask>
|
65 |
+
<g id="j"></g>
|
66 |
+
<polygon id="Shape" fill="url(#linearGradient-12)" fill-rule="nonzero" mask="url(#mask-11)" points="17.2892223 9.4886212 13.6298185 13.1243405 17.2889839 16.7595819 23.5744581 13.1241015"></polygon>
|
67 |
+
</g>
|
68 |
+
<path d="M94.9441003,26.5394923 C94.4323323,26.5394923 93.9653976,26.444878 93.5425809,26.2558885 C93.1197641,26.06666 92.7644558,25.7756496 92.4775501,25.383335 L92.3917188,25.383335 C92.4489331,25.8430264 92.4775501,26.2788452 92.4775501,26.6904928 L92.4775501,29.9300747 L91.2880352,29.9300747 L91.2880352,18.5230861 L92.255768,18.5230861 L92.420316,19.6006371 L92.4775501,19.6006371 C92.7837325,19.1693778 93.1400345,18.8585366 93.5461381,18.6669189 C93.9522815,18.4753011 94.4184809,18.3794923 94.943842,18.3794923 C95.9859791,18.3794923 96.7903564,18.736446 97.3564968,19.4498756 C97.9228757,20.1633051 98.2061844,21.1644002 98.2061844,22.4522051 C98.2061844,23.7452663 97.9181062,24.7494674 97.3426653,25.466003 C96.7667672,26.1818019 95.9673979,26.5394923 94.9441003,26.5394923 L94.9441003,26.5394923 Z M94.7719212,19.3922947 C93.9689748,19.3922947 93.3882873,19.6152115 93.0298589,20.0603484 C92.6714305,20.5056844 92.4873276,21.2145943 92.4775501,22.1867795 L92.4775501,22.452225 C92.4775501,23.558666 92.661653,24.3499851 93.0298589,24.82666 C93.3980648,25.303335 93.9885297,25.5410453 94.8005382,25.5410453 C95.4797159,25.5410453 96.0115358,25.2660428 96.3964349,24.7153211 C96.7808571,24.1648382 96.9732869,23.405774 96.9732869,22.4378895 C96.9732869,21.4566252 96.7808373,20.7030363 96.3964349,20.1788352 C96.0117544,19.6541563 95.4699384,19.3922947 94.7719212,19.3922947 L94.7719212,19.3922947 Z M100.962025,26.3956595 L99.7720134,26.3956595 L99.7720134,15.2187556 L100.962025,15.2187556 L100.962025,26.3956595 Z M107.804597,26.3956595 L107.567791,25.275122 L107.510557,25.275122 C107.118484,25.7687208 106.727862,26.1029766 106.338213,26.2771528 C105.948783,26.4522847 105.462293,26.5395122 104.879459,26.5395122 C104.10038,26.5395122 103.489863,26.3383375 103.047492,25.9362071 C102.60512,25.5341165 102.384292,24.9621105 102.384292,24.2195321 C102.384292,22.6299652 103.653458,21.7965953 106.191292,21.7196615 L107.525343,21.6764161 L107.525343,21.1880538 C107.525343,20.5701941 107.392492,20.1138477 107.127069,19.8197312 C106.862123,19.524878 106.43716,19.3777203 105.854585,19.3777203 C105.199473,19.3777203 104.45855,19.578895 103.631975,19.9810055 L103.266174,19.0687904 C103.653696,18.8580587 104.077467,18.6929816 104.539155,18.5732603 C105.000366,18.453559 105.462531,18.3936088 105.926366,18.3936088 C106.863117,18.3936088 107.557299,18.6017123 108.009229,19.0183972 C108.460663,19.4350821 108.686499,20.1030961 108.686499,21.0227377 L108.686499,26.3954405 L107.804617,26.3954405 L107.804617,26.3956595 L107.804597,26.3956595 Z M105.116027,25.5555998 C105.856493,25.5555998 106.438372,25.3520159 106.861666,24.9451468 C107.284264,24.5382379 107.496269,23.9681832 107.496269,23.2351618 L107.496269,22.5241215 L106.305561,22.5740567 C105.359291,22.608223 104.677471,22.7549228 104.258728,23.0165455 C103.840681,23.2774515 103.631518,23.6833848 103.631518,24.2341065 C103.631518,24.664888 103.761487,24.9931707 104.022399,25.2177402 C104.283032,25.4430662 104.647184,25.5555998 105.116027,25.5555998 Z M109.377342,18.5230861 L110.653185,18.5230861 L112.374043,23.0127028 C112.751549,24.0376904 112.985951,24.7774216 113.077048,25.2325535 L113.134302,25.2325535 C113.196525,24.9878945 113.326971,24.5704928 113.524905,23.9784569 C113.723317,23.386879 114.372426,21.56888 115.471341,18.5230861 L116.748137,18.5230861 L113.37085,27.487785 C113.036508,28.3737183 112.645666,29.0023096 112.198267,29.3740767 C111.751603,29.744888 111.202871,29.9300747 110.553503,29.9300747 C110.190066,29.9300747 109.831638,29.8894574 109.477502,29.808223 L109.477502,28.8529816 C109.740282,28.9103235 110.03456,28.9392334 110.359622,28.9392334 C111.177115,28.9392334 111.759711,28.4795421 112.109077,27.5599403 L112.546202,26.4396018 L109.377342,18.5230861 L109.377342,18.5230861 Z M72.8972755,19.254674 C73.2750402,19.5678845 74.0639166,20.2258835 74.0639166,21.4781085 C74.0639166,22.6959084 73.3735305,23.2733897 72.6831445,23.8159881 C72.4694706,24.0298059 72.2228871,24.2610851 72.2228871,24.623773 C72.2228871,24.9852663 72.4692321,25.183116 72.6507118,25.3314883 L73.2426076,25.7916376 C73.9656648,26.4011349 74.6224258,26.9614136 74.6224258,28.0979791 C74.6224258,29.6457342 73.1267086,31.2094973 70.3002991,31.2094973 C67.9167581,31.2094973 66.7668301,30.0736486 66.7668301,28.8544151 C66.7668301,28.2618815 67.0613273,27.4225386 68.0324186,26.8455351 C69.0507083,26.2197909 70.4321958,26.1383176 71.1714494,26.0876854 C70.9406252,25.7916575 70.6783023,25.478666 70.6783023,24.9690393 C70.6783023,24.6894973 70.7608148,24.5246391 70.8426317,24.3260926 C70.6611321,24.3428173 70.4806063,24.3593031 70.3160782,24.3593031 C68.574473,24.3593031 67.5883975,23.0583574 67.5883975,21.7746142 C67.5883975,21.0169836 67.9339482,20.1766849 68.6398352,19.5681434 C69.5770233,18.7942857 70.6945187,18.6621404 71.5828591,18.6621404 L74.9677778,18.6621404 L73.9158433,19.2549129 L72.8972953,19.2549129 L72.8972953,19.254674 L72.8972755,19.254674 Z M71.7299388,26.5662519 C71.5985587,26.5490493 71.5160264,26.5490493 71.3524323,26.5490493 C71.2045975,26.5490493 70.3158,26.5827377 69.6263678,26.813778 C69.2648591,26.9444699 68.2126662,27.3396516 68.2126662,28.5094276 C68.2126662,29.678009 69.3473517,30.5190443 71.1061072,30.5190443 C72.682906,30.5190443 73.5220808,29.7599801 73.5220808,28.73999 C73.5221007,27.8984968 72.9795693,27.455769 71.7299388,26.5662519 Z M72.2068894,23.4370533 C72.5843958,23.0578795 72.6168483,22.5315281 72.6168483,22.2347835 C72.6168483,21.0494774 71.9104646,19.2052165 70.5466441,19.2052165 C70.1187995,19.2052165 69.6590389,19.4190543 69.3960007,19.7487705 C69.1169647,20.0944948 69.0339752,20.538656 69.0339752,20.9672872 C69.0339752,22.0704032 69.6749969,23.8984171 71.0891556,23.8984171 C71.5000684,23.8984171 71.9429171,23.7008263 72.2068894,23.4370533 L72.2068894,23.4370533 Z M62.5500896,26.3027178 C59.941408,26.3027178 58.5465858,24.2639721 58.5465858,22.4223395 C58.5465858,20.2684121 60.3020026,18.427994 62.7971699,18.427994 C65.2081355,18.427994 66.7179427,20.3178895 66.7179427,22.3076356 C66.7181613,24.2467695 65.2255442,26.3027178 62.5500896,26.3027178 Z M64.6009972,24.9711896 C64.9954354,24.4445993 65.0939058,23.7873171 65.0939058,23.1455849 C65.0939058,21.6983972 64.4047122,18.9369238 62.3698022,18.9369238 C61.8284831,18.9369238 61.2871442,19.1510005 60.8934214,19.4969637 C60.2533338,20.071558 60.1379316,20.7952812 60.1379316,21.5029766 C60.1379316,23.129338 60.9420505,25.8083823 62.928073,25.8083823 C63.5679023,25.8083823 64.224405,25.4965854 64.6009972,24.9711896 L64.6009972,24.9711896 Z M53.6561525,26.3027178 C51.0469741,26.3027178 49.6519133,24.2639721 49.6519133,22.4223395 C49.6519133,20.2684121 51.4080257,18.427994 53.9024975,18.427994 C56.3141984,18.427994 57.8237273,20.3178895 57.8237273,22.3076356 C57.8239857,24.2467695 56.3311302,26.3027178 53.6561525,26.3027178 Z M55.7075172,24.9711896 C56.1012399,24.4445993 56.1999687,23.7873171 56.1999687,23.1455849 C56.1999687,21.6983972 55.5102782,18.9369238 53.4753683,18.9369238 C52.9342678,18.9369238 52.3924717,19.1510005 51.9989676,19.4969637 C51.3588998,20.071558 51.2441932,20.7952812 51.2441932,21.5029766 C51.2441932,23.129338 52.047855,25.8083823 54.0341359,25.8083823 C54.6742036,25.8083823 55.3302691,25.4965854 55.7075172,24.9711896 L55.7075172,24.9711896 Z M48.3984871,26.0449179 L46.0389923,26.5903833 C45.0817524,26.7394724 44.224215,26.8706421 43.3172934,26.8706421 C38.7633686,26.8706421 37.0317993,23.5151817 37.0317993,20.8870085 C37.0317993,17.680896 39.489526,14.7065007 43.6969461,14.7065007 C44.5881284,14.7065007 45.4452285,14.8383873 46.2204919,15.0534196 C47.4577019,15.4005973 48.0350705,15.8299253 48.3982486,16.0781882 L47.0284463,17.3838925 L46.451336,17.5155401 L46.8636599,16.8541961 C46.3030044,16.3092086 45.2792298,15.3011847 43.3332712,15.3011847 C40.7264975,15.3011847 38.7629115,17.2854555 38.7629115,20.1776406 C38.7629115,23.2841414 41.0069643,26.209776 44.6026754,26.209776 C45.659598,26.209776 46.2028646,25.9952414 46.698158,25.796436 L46.698158,23.136008 L44.2075217,23.2681334 L45.5267672,22.5566351 L49.0244848,22.5566351 L48.5959446,22.9697362 C48.4795885,23.0693678 48.4636107,23.1028173 48.4307011,23.2337481 C48.4135309,23.3828372 48.39803,23.8625983 48.39803,24.0276954 L48.39803,26.0449378 L48.3984871,26.0449378 L48.3984871,26.0449179 Z" id="Shape" fill="#F9F9F9" fill-rule="nonzero"></path>
|
69 |
+
<path d="M78.1115582,25.5689796 C77.5668806,25.5192832 77.4528695,25.4206073 77.4528695,24.7752713 L77.4528695,15.4204082 C77.4562082,15.3848084 77.4583545,15.3482529 77.4616732,15.3138278 C77.5282277,14.7356297 77.6930142,14.6364759 78.2050008,14.3385565 L75.8450888,14.3385565 L74.6074217,14.9337183 L75.8687177,14.9337183 L75.8687177,14.9411249 L75.8677638,14.9351518 L75.8677638,25.1393927 C75.8677638,25.4693479 75.80266,25.5195222 75.422749,26.0148133 L78.3431376,26.0148133 L78.9536146,25.6521254 C78.6734061,25.6179592 78.3924822,25.6019512 78.1115582,25.5689796 L78.1115582,25.5689796 Z M84.8246187,25.7209358 C84.6450666,25.8196117 84.4647793,25.9350124 84.2851875,26.0164858 C83.74361,26.2625784 83.18679,26.3285217 82.6943186,26.3285217 C82.1713422,26.3285217 81.3514641,26.2945943 80.5151311,25.6879642 C79.3528223,24.8665406 78.8448698,23.4549925 78.8448698,22.2242708 C78.8448698,19.680438 80.9090924,18.4330114 82.5965437,18.4330114 C83.1865317,18.4330114 83.7934712,18.5804281 84.284949,18.8929617 C85.1034162,19.4336287 85.3163349,20.1394326 85.430346,20.5171528 L81.5811357,22.077113 L80.3193628,22.1755301 C80.7283479,24.2601493 82.13728,25.4738875 83.6942655,25.4738875 C84.5296446,25.4738875 85.1360873,25.1790543 85.6929272,24.9004679 L84.8246187,25.7209358 L84.8246187,25.7209358 Z M83.2850419,20.8287108 C83.5957752,20.7142658 83.7595879,20.6153509 83.7595879,20.3857442 C83.7595879,19.7296565 83.0226991,18.9741762 82.1372403,18.9741762 C81.4811748,18.9741762 80.2532852,19.483325 80.2532852,21.2556894 C80.2532852,21.5347536 80.2861948,21.8300647 80.3031266,22.1265505 L83.2850419,20.8287108 L83.2850419,20.8287108 Z M86.4059485,18.5453061 L86.4059485,19.6283524 L86.2745685,19.6283524 L86.2745685,18.5453061 L85.9168555,18.5453061 L85.9168555,18.4329915 L86.7634429,18.4329915 L86.7634429,18.5453061 L86.4059485,18.5453061 L86.4059485,18.5453061 Z M87.8797459,19.6283524 L87.8797459,18.5352713 L87.873784,18.5352713 L87.5408725,19.6283524 L87.4380896,19.6283524 L87.1023163,18.5352713 L87.0980039,18.5352713 L87.0980039,19.6283524 L86.9787662,19.6283524 L86.9787662,18.4330114 L87.1831396,18.4330114 L87.4869572,19.3992235 L87.4912497,19.3992235 L87.7905362,18.4330114 L87.9977912,18.4330114 L87.9977912,19.6283524 L87.8797459,19.6283524 L87.8797459,19.6283524 Z" id="Shape" fill="#F9F9F9" fill-rule="nonzero"></path>
|
70 |
+
<path d="M40.3084502,11.4881832 L39.4885721,11.4881832 C39.4885721,11.3751717 39.4108291,11.0552514 39.2553432,10.5281832 L38.0717703,10.5281832 C37.9112963,11.0466501 37.8309301,11.3665505 37.8309301,11.4881832 L37.0599394,11.4881832 C37.0599394,11.4215032 37.2593048,10.8738875 37.6580355,9.84557491 C38.0567464,8.81724241 38.2561316,8.25073171 38.2561316,8.14658039 L39.2245799,8.14658039 C39.2245799,8.24406172 39.4051057,8.80219014 39.7663958,9.82120458 C40.1276859,10.840219 40.3084502,11.3957193 40.3084502,11.4881832 L40.3084502,11.4881832 Z M39.1248773,10.0379094 C38.8327649,9.15506222 38.686818,8.6777103 38.686818,8.60577402 L38.6458003,8.60577402 C38.6458003,8.67245396 38.4946069,9.14980587 38.1924587,10.0379094 L39.1248773,10.0379094 L39.1248773,10.0379094 Z M43.6118104,11.4881832 L42.9791354,11.4881832 C42.9791354,11.4179393 42.744257,11.0476058 42.2746793,10.3769438 C41.7829432,9.67020408 41.5027346,9.18709806 41.4345506,8.92692882 L41.3935328,8.92692882 C41.4362199,9.30154306 41.4577026,9.64033848 41.4577026,9.94331508 C41.4577026,10.3659731 41.4696263,10.8810951 41.4934739,11.488442 L40.8631836,11.488442 C40.8886806,10.9580289 40.9015781,10.3755301 40.9015781,9.74070682 C40.9015781,9.1161772 40.8887004,8.58478845 40.8631836,8.14683922 L41.6239,8.14683922 C41.6239,8.23763066 41.8347122,8.59960179 42.256575,9.23251369 C42.7056439,9.90484818 42.9636543,10.3609557 43.0302088,10.6005973 L43.0686034,10.6005973 C43.0276055,10.2190343 43.0070767,9.87687407 43.0070767,9.57393728 C43.0070767,9.11044301 42.9951331,8.63448482 42.9713054,8.14683922 L43.6118501,8.14683922 C43.5877443,8.57116974 43.576059,9.10253858 43.576059,9.74070682 C43.5758006,10.3836336 43.5877244,10.9661324 43.6118104,11.4881832 L43.6118104,11.4881832 Z M47.3246327,9.70176207 C47.3246327,10.1877153 47.1691666,10.6120657 46.8584134,10.9747536 C46.5474416,11.3376804 46.1119658,11.5187855 45.5518071,11.5187855 C45.2990233,11.5187855 44.9506108,11.5084918 44.5065698,11.4879443 C44.5287281,10.9711697 44.5399563,10.3884121 44.5399563,9.74022897 C44.5399563,9.11759084 44.528748,8.586222 44.5065698,8.14634146 L44.9549233,8.14634146 C45.0283538,8.14634146 45.1375755,8.14371329 45.2828268,8.13869587 C45.4278,8.13367845 45.5227131,8.13105027 45.5670696,8.13105027 C46.1835481,8.13105027 46.6304509,8.28515679 46.9082548,8.59313091 C47.18584,8.90110503 47.3246327,9.27048283 47.3246327,9.70176207 L47.3246327,9.70176207 Z M46.6254032,9.81210553 C46.6254032,9.48358387 46.5297746,9.20690891 46.3385173,8.98160279 C46.1472601,8.75677451 45.8551279,8.64426083 45.462359,8.64426083 C45.3889285,8.64426083 45.288272,8.65190642 45.1599723,8.66743654 C45.1769041,9.00979592 45.1854892,9.36722748 45.1854892,9.74020906 C45.1854892,10.1492484 45.1940743,10.5547038 45.2109862,10.9568143 C45.3205841,10.9789365 45.4320977,10.9901409 45.5438977,10.9902638 C45.9111497,10.9902638 46.1830116,10.8758387 46.3597417,10.6474067 C46.5364717,10.4189945 46.6254032,10.1406272 46.6254032,9.81210553 L46.6254032,9.81210553 Z M50.7484229,11.4881832 L49.9900713,11.4881832 C49.7918984,10.8825087 49.6400094,10.5085913 49.5341264,10.36667 C49.4282434,10.2245097 49.257495,10.153549 49.0218814,10.153549 C48.9226757,10.153549 48.8279811,10.1545047 48.7376188,10.1561772 C48.7376188,10.5960577 48.7452302,11.0399602 48.7607509,11.4881832 L48.0486636,11.4881832 C48.070822,10.9713888 48.0820502,10.3886511 48.0820502,9.74044798 C48.0820502,9.11782977 48.0708418,8.58644102 48.0486636,8.14658039 L48.4917309,8.14658039 C48.5430031,8.14658039 48.6500984,8.14395222 48.8132155,8.13893479 C48.9763326,8.13391737 49.127049,8.13126929 49.2653647,8.13126929 C50.0492331,8.13126929 50.4412865,8.39982081 50.4412865,8.93718268 C50.4412865,9.36318566 50.2175967,9.65993031 49.770217,9.82789447 L49.770217,9.86636137 C49.9426346,9.91414634 50.093828,10.0491389 50.2235586,10.2703833 C50.3530308,10.4918666 50.5280717,10.8977999 50.7484229,11.4881832 L50.7484229,11.4881832 Z M49.7878443,9.12686909 C49.7878443,8.78640119 49.5691624,8.6160677 49.1320371,8.6160677 C48.9715432,8.6160677 48.8296306,8.62801394 48.7068356,8.65190642 C48.7256752,8.91711299 48.7349757,9.26283723 48.7349757,9.68884022 C48.8289549,9.69242409 48.9083672,9.69385764 48.9732126,9.69385764 C49.5162209,9.69409657 49.7878443,9.50510702 49.7878443,9.12686909 L49.7878443,9.12686909 Z M54.420446,9.75571926 C54.420446,10.280896 54.2599521,10.716436 53.9387457,11.0621603 C53.6175195,11.4076655 53.2204581,11.5806272 52.7475615,11.5806272 C52.2966245,11.5806272 51.9190982,11.4219811 51.6152807,11.10445 C51.3112246,10.7871578 51.1593158,10.3836336 51.1593158,9.89453459 C51.1593158,9.3693778 51.3198097,8.93381782 51.641036,8.58809358 C51.9620238,8.24260826 52.3590852,8.06962668 52.8322004,8.06962668 C53.2831572,8.06962668 53.660445,8.22779492 53.9645011,8.54437033 C54.2685571,8.86096565 54.420446,9.26450971 54.420446,9.75571926 L54.420446,9.75571926 Z M53.713625,9.8300448 C53.713625,9.47237432 53.6222691,9.18231956 53.4396169,8.95988054 C53.2567063,8.73744151 53.0313471,8.62634146 52.7633009,8.62634146 C52.5138557,8.62634146 52.3020896,8.73839721 52.1280026,8.96250871 C51.9539156,9.18662021 51.8663952,9.46976605 51.8663952,9.81212544 C51.8663952,10.1678845 51.9582082,10.4574614 52.1418143,10.6808761 C52.3254403,10.9042708 52.5503424,11.0158487 52.8169578,11.0158487 C53.0661645,11.0158487 53.2781691,10.9033151 53.4522561,10.678228 C53.6263431,10.4533997 53.713625,10.1704928 53.713625,9.8300448 L53.713625,9.8300448 Z M55.868965,11.4881832 L55.144,11.4881832 C55.1661782,10.95777 55.1773865,10.3752713 55.1773865,9.74044798 C55.1773865,9.11589846 55.1661981,8.58452962 55.144,8.14658039 L55.868965,8.14658039 C55.8467868,8.57783972 55.8355784,9.10896964 55.8355784,9.74044798 C55.8355784,10.3853061 55.8467868,10.9680438 55.868965,11.4881832 Z M59.5820257,9.70176207 C59.5820257,10.1877153 59.4265398,10.6120657 59.1158065,10.9747536 C58.8048545,11.3376804 58.3693787,11.5187855 57.8092002,11.5187855 C57.5564164,11.5187855 57.2080039,11.5084918 56.763943,11.4879443 C56.7861411,10.9711697 56.7973494,10.3884121 56.7973494,9.74022897 C56.7973494,9.11759084 56.7861609,8.586222 56.763943,8.14634146 L57.2122965,8.14634146 C57.2857469,8.14634146 57.3949686,8.14371329 57.5402,8.13869587 C57.6852129,8.13367845 57.7801062,8.13105027 57.8244825,8.13105027 C58.4409412,8.13105027 58.8878439,8.28515679 59.1656478,8.59313091 C59.4432331,8.90110503 59.5820257,9.27048283 59.5820257,9.70176207 L59.5820257,9.70176207 Z M58.8828161,9.81210553 C58.8828161,9.48358387 58.7871875,9.20690891 58.5959104,8.98160279 C58.4046532,8.75677451 58.1125408,8.64426083 57.7197521,8.64426083 C57.6463017,8.64426083 57.5456651,8.65190642 57.4173654,8.66743654 C57.4342971,9.00979592 57.4428624,9.36722748 57.4428624,9.74020906 C57.4428624,10.1492484 57.4514673,10.5547038 57.4683792,10.9568143 C57.5779773,10.9789356 57.6894908,10.99014 57.8012908,10.9902638 C58.1685229,10.9902638 58.4404046,10.8758387 58.6171148,10.6474067 C58.7938648,10.4189945 58.8828161,10.1406272 58.8828161,9.81210553 Z M64.507972,11.4881832 L63.6880938,11.4881832 C63.6880938,11.3751717 63.6103509,11.0552514 63.4546265,10.5281832 L62.2710735,10.5281832 C62.1105796,11.0466501 62.0301935,11.3665505 62.0301935,11.4881832 L61.2594612,11.4881832 C61.2594612,11.4215032 61.4588066,10.8738875 61.8575573,9.84557491 C62.256288,8.81724241 62.4556534,8.25073171 62.4556534,8.14658039 L63.4241016,8.14658039 C63.4241016,8.24406172 63.6048659,8.80219014 63.9659176,9.82120458 C64.3269692,10.840219 64.507972,11.3957193 64.507972,11.4881832 Z M63.324419,10.0379094 C63.0322867,9.15506222 62.8860814,8.6777103 62.8860814,8.60577402 L62.8450637,8.60577402 C62.8450637,8.67245396 62.6941088,9.14980587 62.3919805,10.0379094 L63.324419,10.0379094 L63.324419,10.0379094 Z M67.4960678,9.02152315 C67.4960678,9.43056247 67.3443776,9.73256346 67.0412755,9.92752613 C66.7381733,10.1224888 66.3663903,10.2201891 65.925668,10.2201891 C65.8453217,10.2201891 65.7883261,10.2185167 65.7539857,10.2151717 C65.7539857,10.5370035 65.7632663,10.961115 65.7821258,11.4881832 L65.0621489,11.4881832 C65.0843072,10.9938477 65.0955354,10.4110901 65.0955354,9.74044798 C65.0955354,9.12449975 65.084347,8.59313091 65.0621489,8.14658039 L65.5078593,8.14658039 C65.5710552,8.14658039 65.6921808,8.14395222 65.8715341,8.13893479 C66.0508874,8.13391737 66.2061349,8.13126929 66.3377534,8.13126929 C66.6620798,8.13126929 66.9363264,8.20485814 67.1600163,8.35203584 C67.383726,8.49923345 67.4960678,8.72215032 67.4960678,9.02152315 L67.4960678,9.02152315 Z M66.8352526,9.16272773 C66.8352526,8.79667496 66.5927034,8.61343952 66.1076644,8.61343952 C65.9862805,8.61343952 65.8582193,8.62632155 65.7234807,8.65190642 C65.7423202,8.97541065 65.7516208,9.3414435 65.7516208,9.75048283 C65.794288,9.7540667 65.8439107,9.75550025 65.9001909,9.75550025 C66.5235654,9.75571926 66.8352526,9.55814833 66.8352526,9.16272773 L66.8352526,9.16272773 Z M70.5685838,9.02152315 C70.5685838,9.43056247 70.4169135,9.73256346 70.1140498,9.92752613 C69.8109477,10.1224888 69.4389262,10.2201891 68.9982437,10.2201891 C68.9178576,10.2201891 68.8608819,10.2185167 68.8265216,10.2151717 C68.8265216,10.5370035 68.835842,10.961115 68.8546617,11.4881832 L68.1347047,11.4881832 C68.1568829,10.9938477 68.1681111,10.4110901 68.1681111,9.74044798 C68.1681111,9.12449975 68.1569028,8.59313091 68.1347047,8.14658039 L68.5804151,8.14658039 C68.6436309,8.14658039 68.7647565,8.14395222 68.9440899,8.13893479 C69.1234234,8.13391737 69.2786708,8.13126929 69.4103092,8.13126929 C69.7346157,8.13126929 70.0088822,8.20485814 70.2325721,8.35203584 C70.4562421,8.49923345 70.5685838,8.72215032 70.5685838,9.02152315 L70.5685838,9.02152315 Z M69.9077687,9.16272773 C69.9077687,8.79667496 69.6652393,8.61343952 69.1802004,8.61343952 C69.0588164,8.61343952 68.9307353,8.62632155 68.7960166,8.65190642 C68.8148363,8.97541065 68.8241567,9.3414435 68.8241567,9.75048283 C68.8668239,9.7540667 68.9164467,9.75550025 68.9727268,9.75550025 C69.5960814,9.75571926 69.9077687,9.55814833 69.9077687,9.16272773 L69.9077687,9.16272773 Z M75.5920665,9.75571926 C75.5920665,10.280896 75.4315726,10.716436 75.1103463,11.0621603 C74.7891399,11.4078845 74.3920586,11.5806272 73.9191621,11.5806272 C73.4682251,11.5806272 73.0906988,11.4219811 72.7869011,11.10445 C72.4830637,10.7871578 72.3309363,10.3836336 72.3309363,9.89453459 C72.3309363,9.3693778 72.4914302,8.93381782 72.8126366,8.58809358 C73.1338628,8.24236934 73.5309441,8.06962668 74.0038208,8.06962668 C74.4547777,8.06962668 74.8322841,8.22779492 75.1361016,8.54437033 C75.4399192,8.86096565 75.5920665,9.26450971 75.5920665,9.75571926 L75.5920665,9.75571926 Z M74.8849871,9.8300448 C74.8849871,9.47237432 74.7936312,9.18231956 74.610979,8.95988054 C74.4283268,8.73744151 74.2027092,8.62634146 73.9346828,8.62634146 C73.6852178,8.62634146 73.4734517,8.73839721 73.2993647,8.96250871 C73.1252777,9.18662021 73.0379958,9.46976605 73.0379958,9.81212544 C73.0379958,10.1678845 73.1298286,10.4574614 73.3134348,10.6808761 C73.4970409,10.9042708 73.721943,11.0158487 73.9883199,11.0158487 C74.2377651,11.0158487 74.4495312,10.9033151 74.6236182,10.6782479 C74.7979436,10.4533997 74.8849871,10.1704928 74.8849871,9.8300448 L74.8849871,9.8300448 Z M79.0642671,11.4881832 L78.4315921,11.4881832 C78.4315921,11.4179393 78.1969125,11.0476058 77.727136,10.3769438 C77.2353999,9.67020408 76.9551715,9.18709806 76.8869875,8.92692882 L76.8459697,8.92692882 C76.8886568,9.30154306 76.9101394,9.64033848 76.9101394,9.94331508 C76.9101394,10.3659731 76.9220632,10.8810951 76.9459306,11.488442 L76.3156205,11.488442 C76.3411373,10.9580289 76.354015,10.3755301 76.354015,9.74070682 C76.354015,9.1161772 76.3411771,8.58478845 76.3156205,8.14683922 L77.0763567,8.14683922 C77.0763567,8.23763066 77.2874074,8.59960179 77.7090318,9.23251369 C78.1583193,9.90484818 78.4161111,10.3609557 78.4826656,10.6005973 L78.5210601,10.6005973 C78.4800424,10.2190343 78.4595335,9.87687407 78.4595335,9.57393728 C78.4595335,9.11044301 78.4476097,8.63448482 78.4237423,8.14683922 L79.064287,8.14683922 C79.040201,8.57116974 79.0285157,9.10253858 79.0285157,9.74070682 C79.0284958,10.3836336 79.0404196,10.9661324 79.0642671,11.4881832 L79.0642671,11.4881832 Z" id="Shape" fill="#F9F9FA" fill-rule="nonzero"></path>
|
71 |
+
</g>
|
72 |
+
</g>
|
73 |
+
</g>
|
74 |
+
</g>
|
75 |
+
</svg>
|
assets/img/ios-download.svg
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2 |
+
<svg width="122px" height="40px" viewBox="0 0 122 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
3 |
+
<!-- Generator: Sketch 45.1 (43504) - http://www.bohemiancoding.com/sketch -->
|
4 |
+
<title>graphic-defender-download-ios</title>
|
5 |
+
<desc>Created with Sketch.</desc>
|
6 |
+
<defs></defs>
|
7 |
+
<g id="Security-Plugin" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
8 |
+
<g id="Advanced-Tools---2-Factor---New" transform="translate(-690.000000, -978.000000)">
|
9 |
+
<g id="graphic-defender-download-ios" transform="translate(690.000000, 978.000000)">
|
10 |
+
<g>
|
11 |
+
<path d="M121.876094,34.4521429 C121.876094,37.425 119.464449,39.8359524 116.489746,39.8359524 L5.38753906,39.8359524 C2.41259766,39.8361905 0,37.4252381 0,34.4521429 L0,5.38333333 C0,2.41071429 2.41259766,0 5.38753906,0 L116.489508,0 C119.464211,0 121.875855,2.41071429 121.875855,5.38333333 L121.875855,34.4521429 L121.876094,34.4521429 Z" id="path6" fill="#000000" fill-rule="nonzero"></path>
|
12 |
+
<g id="g3447" transform="translate(8.450693, 5.437730)" fill-rule="nonzero" fill="#FFFFFF">
|
13 |
+
<g id="g3449">
|
14 |
+
<path d="M19.6864359,14.9573036 C19.6549428,11.4599596 22.5523066,9.75849037 22.6847948,9.67927656 C21.0438965,7.28875568 18.5005584,6.96213435 17.6068063,6.93609145 C15.4707064,6.71147147 13.3986786,8.21327851 12.3105382,8.21327851 C11.2006785,8.21327851 9.5250292,6.95779387 7.71906368,6.99468797 C5.39509121,7.03049695 3.2209824,8.37496149 2.02858905,10.4627337 C-0.43221544,14.7196622 1.40307123,20.9753829 3.76070871,24.4163007 C4.94007044,26.1014931 6.31816439,27.9830924 8.12195797,27.9169 C9.88665669,27.8441969 10.5458395,26.792715 12.6754236,26.792715 C14.7854603,26.792715 15.4044623,27.9169 17.2440929,27.8745803 C19.1380218,27.8441969 20.3304152,26.181792 21.4685101,24.4814079 C22.8314005,22.5498931 23.3787286,20.6476765 23.400448,20.5500156 C23.3559233,20.5348239 19.7222729,19.1491248 19.6864359,14.9573036 Z" id="path3451"></path>
|
15 |
+
<path d="M16.2113369,4.67252969 C17.1604733,3.48649278 17.8098824,1.87291831 17.6296117,0.23547119 C16.2558616,0.296237948 14.5378595,1.18495179 13.5485423,2.34494581 C12.6732517,3.3671295 11.8913544,5.04255585 12.0933446,6.61815109 C13.6365057,6.73317388 15.2209337,5.84011956 16.2113369,4.67252969 L16.2113369,4.67252969 Z" id="path3453"></path>
|
16 |
+
</g>
|
17 |
+
</g>
|
18 |
+
<g id="g3455" transform="translate(35.993230, 14.542779)" fill-rule="nonzero" fill="#FFFFFF">
|
19 |
+
<path d="M10.6202177,12.3060081 L8.54907005,12.3060081 L7.41454443,8.74379054 L3.47106471,8.74379054 L2.39034698,12.3060081 L0.373919215,12.3060081 L4.28091901,0.178612084 L6.69406595,0.178612084 L10.6202177,12.3060081 L10.6202177,12.3060081 Z M7.07254515,7.24928127 L6.0465473,4.08256192 C5.93801953,3.75905534 5.73464396,2.99722012 5.43459659,1.79796756 L5.39811667,1.79796756 C5.27864492,2.31375552 5.08621332,3.07559073 4.82173388,4.08256192 L3.81397599,7.24928127 L7.07254515,7.24928127 L7.07254515,7.24928127 Z" id="path3457"></path>
|
20 |
+
<path d="M20.6677006,7.82612539 C20.6677006,9.31334438 20.2655095,10.4889035 19.4611271,11.3518915 C18.7406487,12.1201057 17.8459785,12.5037572 16.7780288,12.5037572 C15.6252632,12.5037572 14.7971689,12.0900333 14.292834,11.2625854 L14.2563541,11.2625854 L14.2563541,15.8691369 L12.3119741,15.8691369 L12.3119741,6.44005917 C12.3119741,5.50507959 12.2873502,4.54549528 12.2399263,3.56130625 L13.9499227,3.56130625 L14.0584505,4.94737247 L14.0949304,4.94737247 C14.743361,3.90303855 15.727407,3.38178288 17.0479802,3.38178288 C18.080362,3.38178288 18.9422002,3.78912778 19.6316708,4.60472888 C20.3229653,5.42124126 20.6677006,6.49473634 20.6677006,7.82612539 L20.6677006,7.82612539 Z M18.6868408,7.89720571 C18.6868408,7.04606446 18.4953212,6.34437413 18.110458,5.79213472 C17.6900269,5.21620188 17.1255,4.92823546 16.4177895,4.92823546 C15.9380785,4.92823546 15.5021435,5.08862182 15.1127203,5.40483811 C14.7223851,5.72378826 14.4670256,6.14024603 14.3475539,6.65603399 C14.287362,6.89661353 14.2572661,7.09345134 14.2572661,7.24836998 L14.2572661,8.70642781 C14.2572661,9.34250554 14.4524337,9.87925307 14.8427688,10.3175817 C15.233104,10.7559103 15.740175,10.974619 16.3639816,10.974619 C17.0963161,10.974619 17.6663149,10.6921203 18.0739781,10.1289455 C18.4825532,9.56485936 18.6868408,8.82124986 18.6868408,7.89720571 L18.6868408,7.89720571 Z" id="path3459"></path>
|
21 |
+
<path d="M30.7334235,7.82612539 C30.7334235,9.31334438 30.3312323,10.4889035 29.525938,11.3518915 C28.8063715,12.1201057 27.9117014,12.5037572 26.8437516,12.5037572 C25.6909861,12.5037572 24.8628918,12.0900333 24.3594689,11.2625854 L24.3229889,11.2625854 L24.3229889,15.8691369 L22.378609,15.8691369 L22.378609,6.44005917 C22.378609,5.50507959 22.3539851,4.54549528 22.3065612,3.56130625 L24.0165576,3.56130625 L24.1250853,4.94737247 L24.1615653,4.94737247 C24.8090839,3.90303855 25.7931298,3.38178288 27.1146151,3.38178288 C28.1460849,3.38178288 29.0079231,3.78912778 29.6992176,4.60472888 C30.3877762,5.42124126 30.7334235,6.49473634 30.7334235,7.82612539 L30.7334235,7.82612539 Z M28.7525636,7.89720571 C28.7525636,7.04606446 28.560132,6.34437413 28.1752688,5.79213472 C27.7548377,5.21620188 27.1921349,4.92823546 26.4835124,4.92823546 C26.0028894,4.92823546 25.5678663,5.08862182 25.1775311,5.40483811 C24.787196,5.72378826 24.5327485,6.14024603 24.4132767,6.65603399 C24.3539969,6.89661353 24.3229889,7.09345134 24.3229889,7.24836998 L24.3229889,8.70642781 C24.3229889,9.34250554 24.5181565,9.87925307 24.9066677,10.3175817 C25.2970029,10.7549991 25.8040738,10.974619 26.4297045,10.974619 C27.162039,10.974619 27.7320378,10.6921203 28.1397009,10.1289455 C28.5482761,9.56485936 28.7525636,8.82124986 28.7525636,7.89720571 L28.7525636,7.89720571 Z" id="path3461"></path>
|
22 |
+
<path d="M41.9874798,8.90508819 C41.9874798,9.9366641 41.6290646,10.7759586 40.9094981,11.4238831 C40.1187958,12.1319524 39.0180141,12.4855314 37.603505,12.4855314 C36.2975238,12.4855314 35.25055,12.2340165 34.4580237,11.7300752 L34.9085507,10.1107198 C35.7621809,10.6265077 36.6988029,10.885313 37.7193288,10.885313 C38.4516633,10.885313 39.0216621,10.7194589 39.4311492,10.3895733 C39.8388124,10.0596877 40.0421879,9.61680267 40.0421879,9.06456326 C40.0421879,8.57246875 39.8743803,8.15783355 39.537853,7.82156896 C39.2031497,7.48530438 38.6440949,7.17273323 37.8634245,6.88385552 C35.738469,6.09194786 34.6769032,4.93188061 34.6769032,3.4063876 C34.6769032,2.40944056 35.0489984,1.59201689 35.7941008,0.955939164 C36.5364673,0.31895015 37.5268972,0.000911286143 38.7653906,0.000911286143 C39.8698203,0.000911286143 40.7872904,0.193192662 41.5196248,0.576844128 L41.0335298,2.16065944 C40.3495313,1.7888547 39.5761569,1.60295233 38.7106707,1.60295233 C38.0266722,1.60295233 37.4922413,1.77154026 37.1092021,2.10689356 C36.7854428,2.4067067 36.6231071,2.77213245 36.6231071,3.20499336 C36.6231071,3.68432988 36.8082427,4.08073935 37.1803379,4.39239921 C37.5040973,4.68036563 38.092336,4.99202549 38.9459662,5.32829008 C39.990204,5.74839299 40.7571944,6.23957622 41.2505854,6.80275106 C41.7421524,7.36410332 41.9874798,8.06670494 41.9874798,8.90508819 L41.9874798,8.90508819 Z" id="path3463"></path>
|
23 |
+
<path d="M48.4161543,5.01936407 L46.2729588,5.01936407 L46.2729588,9.26504621 C46.2729588,10.3449203 46.6505261,10.8844017 47.4074845,10.8844017 C47.7549557,10.8844017 48.0431471,10.8543292 48.2711466,10.7941844 L48.3249545,12.2695566 C47.9419153,12.4126286 47.4375804,12.4846202 46.8128617,12.4846202 C46.0449593,12.4846202 45.4448646,12.2504196 45.0116655,11.7829298 C44.5802904,11.3145287 44.3632349,10.5290001 44.3632349,9.42543258 L44.3632349,5.0175415 L43.0864375,5.0175415 L43.0864375,3.55948367 L44.3632349,3.55948367 L44.3632349,1.95835392 L46.2729588,1.38242108 L46.2729588,3.55948367 L48.4161543,3.55948367 L48.4161543,5.01936407 L48.4161543,5.01936407 Z" id="path3465"></path>
|
24 |
+
<path d="M58.08607,7.86166555 C58.08607,9.20581262 57.7012068,10.3093801 56.9333045,11.1723681 C56.1280102,12.0608721 55.0591484,12.5037572 53.7267192,12.5037572 C52.4426259,12.5037572 51.420276,12.0781865 50.6578456,11.2270453 C49.8954152,10.375904 49.5142,9.30149766 49.5142,8.00656005 C49.5142,6.65147756 49.9063592,5.54153103 50.6934136,4.67854306 C51.4786439,3.81464379 52.5383857,3.38269416 53.8708149,3.38269416 C55.1549082,3.38269416 56.188202,3.80826479 56.9679604,4.66031733 C57.7139748,5.48685387 58.08607,6.55396994 58.08607,7.86166555 L58.08607,7.86166555 Z M56.0687303,7.9245443 C56.0687303,7.11805606 55.8963626,6.42638988 55.5470674,5.84954575 C55.1394042,5.15150057 54.5566375,4.80338926 53.801503,4.80338926 C53.0199207,4.80338926 52.4262099,5.15241185 52.0185468,5.84954575 C51.6692515,6.42730117 51.4968839,7.12990278 51.4968839,7.96099574 C51.4968839,8.76748398 51.6692515,9.45915016 52.0185468,10.035083 C52.4389779,10.7331282 53.0263047,11.0812395 53.7841751,11.0812395 C54.5265415,11.0812395 55.1093083,10.7258379 55.5297394,10.0168573 C55.8881547,9.42907772 56.0687303,8.73012125 56.0687303,7.9245443 L56.0687303,7.9245443 Z" id="path3467"></path>
|
25 |
+
<path d="M64.4062168,5.26996776 C64.2137852,5.2344276 64.0085856,5.21620188 63.7933541,5.21620188 C63.1093555,5.21620188 62.5803966,5.47409586 62.2083014,5.9907951 C61.8845421,6.44643817 61.7222064,7.02237102 61.7222064,7.71768234 L61.7222064,12.3060081 L59.7787385,12.3060081 L59.7969784,6.31521297 C59.7969784,5.3073305 59.7723545,4.38966535 59.7240186,3.56221753 L61.417599,3.56221753 L61.4887349,5.23533889 L61.5425428,5.23533889 C61.7477424,4.66031733 62.0715017,4.19738397 62.5147327,3.85018395 C62.9479318,3.53761281 63.4157869,3.38178288 63.9201218,3.38178288 C64.0997854,3.38178288 64.2621211,3.39454088 64.4062168,3.41732304 L64.4062168,5.26996776 Z" id="path3469"></path>
|
26 |
+
<path d="M73.1021185,7.51993325 C73.1021185,7.86804456 73.0793186,8.1614787 73.0309827,8.40114695 L67.1978429,8.40114695 C67.2206429,9.26504621 67.5024503,9.92572867 68.0441771,10.3813717 C68.5357441,10.7887166 69.1714068,10.9928447 69.9520771,10.9928447 C70.8157393,10.9928447 71.6037057,10.8552405 72.3123282,10.5791208 L72.6169355,11.9278243 C71.7888413,12.2886936 70.8111793,12.468217 69.6830377,12.468217 C68.3259845,12.468217 67.2607708,12.0690737 66.4855724,11.2716983 C65.712198,10.4743229 65.3245988,9.40356171 65.3245988,8.06032593 C65.3245988,6.74169488 65.6848381,5.64359508 66.4062286,4.7678491 C67.161363,3.83286952 68.1818888,3.36537973 69.4659821,3.36537973 C70.7272755,3.36537973 71.6821375,3.83286952 72.3305681,4.7678491 C72.8440231,5.51054731 73.1021185,6.42912374 73.1021185,7.51993325 L73.1021185,7.51993325 Z M71.2480264,7.01599201 C71.2607944,6.44005917 71.1340266,5.94249694 70.8704592,5.52239403 C70.5339319,4.98200134 70.016829,4.71226064 69.3209745,4.71226064 C68.6853118,4.71226064 68.1682089,4.97562234 67.7733137,5.5041683 C67.4495544,5.92427121 67.2571228,6.42821245 67.1978429,7.01508073 L71.2480264,7.01508073 L71.2480264,7.01599201 Z" id="path3471"></path>
|
27 |
+
</g>
|
28 |
+
<g id="g3473" transform="translate(36.661984, 7.639426)" fill-rule="nonzero" fill="#FFFFFF">
|
29 |
+
<g id="g3475">
|
30 |
+
<path d="M3.09476983,2.04913172 C3.09476983,2.65073512 2.91419896,3.10359885 2.55356876,3.40772292 C2.21953823,3.68833487 1.74483635,3.82889641 1.12997464,3.82889641 C0.825101444,3.82889641 0.56422002,3.81560696 0.34579577,3.78902805 L0.34579577,0.501932489 C0.630719207,0.45593053 0.937638529,0.432418417 1.2691114,0.432418417 C1.85481577,0.432418417 2.29626806,0.559690505 2.5939798,0.814234679 C2.9274988,1.10200249 3.09476983,1.51346446 3.09476983,2.04913172 Z M2.52952675,2.06395457 C2.52952675,1.67396019 2.42619724,1.37494745 2.21953823,1.16640523 C2.01287922,0.958374152 1.71107522,0.854103044 1.3136147,0.854103044 C1.14480907,0.854103044 1.00106852,0.865347967 0.881881519,0.88886008 L0.881881519,3.38778873 C0.947869173,3.39801139 1.06859077,3.40261159 1.24404632,3.40261159 C1.65429515,3.40261159 1.97093358,3.28862896 2.19396162,3.06066369 C2.41698966,2.83269843 2.52952675,2.50046205 2.52952675,2.06395457 L2.52952675,2.06395457 Z" id="path3477"></path>
|
31 |
+
<path d="M6.09183701,2.57457632 C6.09183701,2.94514766 5.98594985,3.24876059 5.77417551,3.48694851 C5.55217054,3.73178116 5.25803952,3.85394192 4.8907594,3.85394192 C4.53677911,3.85394192 4.25492487,3.73689249 4.04468513,3.50177137 C3.83495693,3.26716138 3.73009283,2.97121544 3.73009283,2.61444469 C3.73009283,2.24131768 3.83802612,1.93514909 4.05491578,1.6974723 C4.27180543,1.45979551 4.56337879,1.34070155 4.93065891,1.34070155 C5.28463919,1.34070155 5.5690511,1.45775098 5.78440616,1.69236097 C5.98901904,1.92032623 6.09183701,2.21473877 6.09183701,2.57457632 L6.09183701,2.57457632 Z M5.53580151,2.59195484 C5.53580151,2.36961204 5.48771748,2.17895947 5.39206096,2.01999715 C5.27952387,1.82781118 5.11941429,1.7317182 4.91122069,1.7317182 C4.69586563,1.7317182 4.53217532,1.82781118 4.41963824,2.01999715 C4.32347018,2.17895947 4.27589769,2.37267883 4.27589769,2.60166636 C4.27589769,2.82400917 4.32398172,3.01466173 4.41963824,3.17362406 C4.53575605,3.36581002 4.69740022,3.461903 4.90610536,3.461903 C5.11071825,3.461903 5.27133936,3.36427662 5.38694564,3.16851273 C5.48618288,3.00648361 5.53580151,2.81429764 5.53580151,2.59195484 Z" id="path3479"></path>
|
32 |
+
<path d="M10.110434,1.3897703 L9.355924,3.7992507 L8.86485309,3.7992507 L8.55230691,2.7529617 C8.47301942,2.49177279 8.40856636,2.23211729 8.35843621,1.97450632 L8.34871709,1.97450632 C8.30216766,2.23927315 8.23771461,2.49841752 8.15484639,2.7529617 L7.82286199,3.7992507 L7.32616422,3.7992507 L6.61666905,1.3897703 L7.16758924,1.3897703 L7.4402359,2.53521909 C7.50622355,2.80611952 7.56044597,3.06424162 7.60392621,3.30856314 L7.61364532,3.30856314 C7.65354483,3.10717678 7.71953248,2.85058808 7.81263134,2.54033042 L8.15484639,1.39028144 L8.59169489,1.39028144 L8.91958703,2.51579604 C8.99887452,2.7902744 9.06332758,3.0545301 9.11294621,3.30907427 L9.12778064,3.30907427 C9.16409943,3.06117482 9.21883337,2.79691912 9.29147094,2.51579604 L9.58406737,1.39028144 L10.110434,1.39028144 L10.110434,1.3897703 Z" id="path3481"></path>
|
33 |
+
<path d="M12.8895885,3.7992507 L12.3535027,3.7992507 L12.3535027,2.41919193 C12.3535027,1.99392937 12.1918585,1.78129809 11.8675471,1.78129809 C11.7084606,1.78129809 11.580066,1.83956724 11.4803172,1.95661667 C11.3815915,2.0736661 11.3314614,2.21167198 11.3314614,2.36961204 L11.3314614,3.79873957 L10.7953756,3.79873957 L10.7953756,2.07826629 C10.7953756,1.86665728 10.7887257,1.63715862 10.7759374,1.38874804 L11.2470586,1.38874804 L11.2721236,1.76545297 L11.2869581,1.76545297 C11.349365,1.64840354 11.4424639,1.55179943 11.5647201,1.47461836 C11.7099952,1.38465897 11.8726624,1.33916815 12.0506757,1.33916815 C12.2757498,1.33916815 12.4629706,1.41174902 12.6118265,1.55742189 C12.7970011,1.73580726 12.8895885,2.00210749 12.8895885,2.35581145 L12.8895885,3.7992507 L12.8895885,3.7992507 Z" id="path3483"></path>
|
34 |
+
<polygon id="path3485" points="14.3679165 3.7992507 13.8323423 3.7992507 13.8323423 0.284189882 14.3679165 0.284189882"></polygon>
|
35 |
+
<path d="M17.5240702,2.57457632 C17.5240702,2.94514766 17.4181831,3.24876059 17.2064087,3.48694851 C16.9844038,3.73178116 16.6897612,3.85394192 16.3229926,3.85394192 C15.9685008,3.85394192 15.6866466,3.73689249 15.4769183,3.50177137 C15.2671901,3.26716138 15.162326,2.97121544 15.162326,2.61444469 C15.162326,2.24131768 15.2702593,1.93514909 15.487149,1.6974723 C15.7040386,1.45979551 15.995612,1.34070155 16.3623806,1.34070155 C16.7168724,1.34070155 17.0007728,1.45775098 17.2166394,1.69236097 C17.4212523,1.92032623 17.5240702,2.21473877 17.5240702,2.57457632 L17.5240702,2.57457632 Z M16.9675232,2.59195484 C16.9675232,2.36961204 16.9194392,2.17895947 16.8237826,2.01999715 C16.7117571,1.82781118 16.551136,1.7317182 16.3434539,1.7317182 C16.1275873,1.7317182 15.963897,1.82781118 15.8518715,2.01999715 C15.7557034,2.17895947 15.7081309,2.37267883 15.7081309,2.60166636 C15.7081309,2.82400917 15.7562149,3.01466173 15.8518715,3.17362406 C15.9679893,3.36581002 16.1296334,3.461903 16.3383386,3.461903 C16.5429515,3.461903 16.703061,3.36427662 16.8186673,3.16851273 C16.9184161,3.00648361 16.9675232,2.81429764 16.9675232,2.59195484 L16.9675232,2.59195484 Z" id="path3487"></path>
|
36 |
+
<path d="M20.1185616,3.7992507 L19.6372098,3.7992507 L19.5973102,3.52170555 L19.5824758,3.52170555 C19.4177624,3.74302609 19.1829692,3.85394192 18.878096,3.85394192 C18.6504641,3.85394192 18.4663125,3.78084992 18.3276873,3.63568818 C18.2018504,3.5038159 18.1389319,3.33974224 18.1389319,3.14500062 C18.1389319,2.85058808 18.2616997,2.62620074 18.5087697,2.47081635 C18.7553282,2.31543195 19.1021471,2.23927315 19.5487147,2.24285108 L19.5487147,2.19787139 C19.5487147,1.88045787 19.3819552,1.72200668 19.0479247,1.72200668 C18.8100622,1.72200668 18.600334,1.78180922 18.4192516,1.90039205 L18.3102952,1.54873263 C18.5343463,1.41021562 18.8110853,1.34070155 19.1374428,1.34070155 C19.7676505,1.34070155 20.0837774,1.67293792 20.0837774,2.33741066 L20.0837774,3.22473735 C20.0837774,3.46548093 20.0955426,3.65715576 20.1185616,3.7992507 Z M19.5620145,2.97121544 L19.5620145,2.59962183 C18.9706833,2.58939917 18.6750177,2.7514283 18.6750177,3.08519807 C18.6750177,3.21093676 18.7087788,3.30498521 18.7778357,3.36785455 C18.8468925,3.4307239 18.934876,3.461903 19.0397401,3.461903 C19.1573926,3.461903 19.267372,3.4245903 19.3676323,3.35047603 C19.4684041,3.27585063 19.5302995,3.18129105 19.5533185,3.06526389 C19.5589453,3.03919611 19.5620145,3.00750587 19.5620145,2.97121544 Z" id="path3489"></path>
|
37 |
+
<path d="M23.1647358,3.7992507 L22.6890109,3.7992507 L22.6639458,3.41232311 L22.6491114,3.41232311 C22.4971863,3.70673565 22.238351,3.85394192 21.8746516,3.85394192 C21.5841013,3.85394192 21.3421466,3.73995929 21.150322,3.51199403 C20.9584974,3.28402876 20.8628409,2.98808282 20.8628409,2.62466734 C20.8628409,2.23467296 20.966682,1.91879284 21.1753871,1.67753812 C21.3774423,1.45263965 21.6250239,1.34019041 21.9196665,1.34019041 C22.2434663,1.34019041 22.4700751,1.44906172 22.5989812,1.66731546 L22.6092119,1.66731546 L22.6092119,0.284189882 L23.1458091,0.284189882 L23.1458091,3.15011195 C23.1458091,3.38472194 23.1519475,3.60093115 23.1647358,3.7992507 L23.1647358,3.7992507 Z M22.6092119,2.78311854 L22.6092119,2.38136809 C22.6092119,2.31185402 22.6040965,2.2556294 22.5943774,2.21269424 C22.564197,2.08388876 22.4992324,1.97552858 22.4005067,1.88812486 C22.3007579,1.80072114 22.1805479,1.75676371 22.0419226,1.75676371 C21.8419136,1.75676371 21.6853847,1.83598931 21.57029,1.99495163 C21.4562183,2.15391396 21.3984151,2.35683371 21.3984151,2.60473316 C21.3984151,2.84292108 21.4531491,3.03612931 21.5631285,3.18486898 C21.6792463,3.34332017 21.8357752,3.42254577 22.031692,3.42254577 C22.2076591,3.42254577 22.3483304,3.35660963 22.4552407,3.22422621 C22.5585702,3.10206545 22.6092119,2.95485918 22.6092119,2.78311854 L22.6092119,2.78311854 Z" id="path3491"></path>
|
38 |
+
<path d="M27.749599,2.57457632 C27.749599,2.94514766 27.6437118,3.24876059 27.4319375,3.48694851 C27.2099325,3.73178116 26.916313,3.85394192 26.5485214,3.85394192 C26.1950526,3.85394192 25.9131984,3.73689249 25.7024471,3.50177137 C25.4927189,3.26716138 25.3878548,2.97121544 25.3878548,2.61444469 C25.3878548,2.24131768 25.4957881,1.93514909 25.7126777,1.6974723 C25.9295674,1.45979551 26.2211408,1.34070155 26.5889324,1.34070155 C26.9424012,1.34070155 27.2273246,1.45775098 27.4421681,1.69236097 C27.646781,1.92032623 27.749599,2.21473877 27.749599,2.57457632 L27.749599,2.57457632 Z M27.194075,2.59195484 C27.194075,2.36961204 27.145991,2.17895947 27.0503345,2.01999715 C26.9372858,1.82781118 26.7776878,1.7317182 26.5689827,1.7317182 C26.3541391,1.7317182 26.1904488,1.82781118 26.0774002,2.01999715 C25.9812321,2.17895947 25.9336597,2.37267883 25.9336597,2.60166636 C25.9336597,2.82400917 25.9817437,3.01466173 26.0774002,3.17362406 C26.193518,3.36581002 26.3551622,3.461903 26.5638673,3.461903 C26.7684802,3.461903 26.9296129,3.36427662 27.0452191,3.16851273 C27.1439448,3.00648361 27.194075,2.81429764 27.194075,2.59195484 L27.194075,2.59195484 Z" id="path3493"></path>
|
39 |
+
<path d="M30.6320829,3.7992507 L30.0965087,3.7992507 L30.0965087,2.41919193 C30.0965087,1.99392937 29.9348645,1.78129809 29.6100416,1.78129809 C29.4509551,1.78129809 29.3225605,1.83956724 29.2233233,1.95661667 C29.124086,2.0736661 29.0744674,2.21167198 29.0744674,2.36961204 L29.0744674,3.79873957 L28.5378701,3.79873957 L28.5378701,2.07826629 C28.5378701,1.86665728 28.5317317,1.63715862 28.5189434,1.38874804 L28.989553,1.38874804 L29.0146181,1.76545297 L29.0294525,1.76545297 C29.092371,1.64840354 29.1854699,1.55179943 29.3072145,1.47461836 C29.4530012,1.38465897 29.6151569,1.33916815 29.7936817,1.33916815 C30.0182443,1.33916815 30.2054651,1.41174902 30.354321,1.55742189 C30.5400071,1.73580726 30.6320829,2.00210749 30.6320829,2.35581145 L30.6320829,3.7992507 L30.6320829,3.7992507 Z" id="path3495"></path>
|
40 |
+
<path d="M34.2399196,1.79100961 L33.6496114,1.79100961 L33.6496114,2.96150391 C33.6496114,3.25898325 33.7544755,3.40772292 33.9621576,3.40772292 C34.0583256,3.40772292 34.1381247,3.39954479 34.2010431,3.38267741 L34.2148545,3.78902805 C34.1089673,3.82889641 33.9698306,3.84883059 33.7984673,3.84883059 C33.586693,3.84883059 33.4219796,3.78442785 33.3027926,3.65562236 C33.183094,3.52681688 33.1237563,3.31009654 33.1237563,3.00597247 L33.1237563,1.79100961 L32.7713106,1.79100961 L32.7713106,1.3897703 L33.1237563,1.3897703 L33.1237563,0.948151494 L33.6490999,0.789700301 L33.6490999,1.38925917 L34.239408,1.38925917 L34.239408,1.79100961 L34.2399196,1.79100961 Z" id="path3497"></path>
|
41 |
+
<path d="M37.0779002,3.7992507 L36.541303,3.7992507 L36.541303,2.42941458 C36.541303,1.9975073 36.3796588,1.78129809 36.0558589,1.78129809 C35.8072542,1.78129809 35.6374256,1.90652565 35.5443267,2.15698076 C35.5284692,2.20962744 35.5192616,2.27403019 35.5192616,2.34967785 L35.5192616,3.79873957 L34.9836874,3.79873957 L34.9836874,0.284189882 L35.5192616,0.284189882 L35.5192616,1.7363184 L35.5294923,1.7363184 C35.6982979,1.4720627 35.9402526,1.34019041 36.2538219,1.34019041 C36.4758268,1.34019041 36.6594669,1.41277128 36.8052536,1.55844415 C36.9868475,1.73989633 37.0779002,2.00977449 37.0779002,2.36654524 L37.0779002,3.7992507 Z" id="path3499"></path>
|
42 |
+
<path d="M40.005399,2.48052787 C40.005399,2.57662085 39.9982376,2.65737985 39.9854493,2.72331599 L38.3777036,2.72331599 C38.384865,2.96150391 38.4615949,3.14295608 38.6104507,3.26869477 C38.7465183,3.38114401 38.9219738,3.43736862 39.1368174,3.43736862 C39.3746798,3.43736862 39.5915695,3.39954479 39.7869748,3.32338599 L39.8708661,3.69549073 C39.6422112,3.79465051 39.3731452,3.8442304 39.0616221,3.8442304 C38.6882036,3.8442304 38.3940726,3.73433683 38.1812752,3.51454969 C37.9674547,3.29476255 37.8615676,2.99983888 37.8615676,2.62977867 C37.8615676,2.26636319 37.9602933,1.96377253 38.1592793,1.72251781 C38.3669614,1.46490684 38.6477926,1.33610135 39.0022844,1.33610135 C39.3491032,1.33610135 39.6125423,1.46490684 39.7905555,1.72251781 C39.9342961,1.92697096 40.005399,2.17998174 40.005399,2.48052787 L40.005399,2.48052787 Z M39.4938668,2.34201086 C39.4979591,2.18304853 39.4626634,2.04606492 39.3900258,1.93054889 C39.2969269,1.78180922 39.1552325,1.70718382 38.9634079,1.70718382 C38.7884639,1.70718382 38.6457464,1.77976469 38.5367901,1.92543756 C38.4477835,2.04146473 38.3950957,2.17998174 38.3777036,2.34201086 L39.4938668,2.34201086 L39.4938668,2.34201086 Z" id="path3501"></path>
|
43 |
+
</g>
|
44 |
+
</g>
|
45 |
+
</g>
|
46 |
+
</g>
|
47 |
+
</g>
|
48 |
+
</g>
|
49 |
+
</svg>
|
changelog.txt
CHANGED
@@ -1,12 +1,22 @@
|
|
1 |
Plugin Name: WP Defender
|
2 |
Author: Hoang Ngo, Aaron Edwards
|
3 |
-
Tested up to: 4.
|
4 |
|
5 |
Change Log:
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
1.6.2 - 2017-05-07
|
8 |
----------------------------------------------------------------------
|
|
|
9 |
- Improvement: Email reports now have unsubscribe link, and link to Reports where email reports can be turned off.
|
|
|
10 |
- Other minor enhancements/fixes
|
11 |
|
12 |
1.6.1 - 2017-21-06
|
1 |
Plugin Name: WP Defender
|
2 |
Author: Hoang Ngo, Aaron Edwards
|
3 |
+
Tested up to: 4.8.1
|
4 |
|
5 |
Change Log:
|
6 |
|
7 |
+
1.7 - 2017-15-08
|
8 |
+
----------------------------------------------------------------------
|
9 |
+
- New: Now you can enable 2 factors authentication with Defender and Google Authenticator app, support for iOS and Android
|
10 |
+
- New: We can define how long the "Remember me" can take affect, via a new Security Tweak, called "Manage Login Duration"
|
11 |
+
- Improvement: IP Lockout logs now have separate tables, better for performance.
|
12 |
+
- Fix: Ignore a file in Scanning section sometimes coming back after couple of scans.
|
13 |
+
- Other minor enhancements/fixes
|
14 |
+
|
15 |
1.6.2 - 2017-05-07
|
16 |
----------------------------------------------------------------------
|
17 |
+
- New: CSV export for Audit Logging.
|
18 |
- Improvement: Email reports now have unsubscribe link, and link to Reports where email reports can be turned off.
|
19 |
+
- Fix: Typo in Audit email.
|
20 |
- Other minor enhancements/fixes
|
21 |
|
22 |
1.6.1 - 2017-21-06
|
languages/wpdef-default.pot
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
# This file is distributed under the GNU General Public License (Version 2 - GPLv2).
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: WP Defender Pro 1.7
|
6 |
"Report-Msgid-Bugs-To: https://wpmudev.org\n"
|
7 |
-
"POT-Creation-Date: 2017-
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=utf-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -152,17 +152,17 @@ msgid "Lockout reports are active scheduled to send %s"
|
|
152 |
msgstr ""
|
153 |
|
154 |
#: app/behavior/report-free.php:129 app/behavior/report.php:224
|
155 |
-
#: app/behavior/utils.php:
|
156 |
msgid "daily"
|
157 |
msgstr ""
|
158 |
|
159 |
#: app/behavior/report-free.php:132 app/behavior/report.php:227
|
160 |
-
#: app/behavior/utils.php:
|
161 |
msgid "weekly"
|
162 |
msgstr ""
|
163 |
|
164 |
#: app/behavior/report-free.php:135 app/behavior/report.php:230
|
165 |
-
#: app/behavior/utils.php:
|
166 |
msgid "monthly"
|
167 |
msgstr ""
|
168 |
|
@@ -204,67 +204,72 @@ msgstr ""
|
|
204 |
msgid "To activate this report you must first enable the Audit Logging module."
|
205 |
msgstr ""
|
206 |
|
207 |
-
#: app/behavior/utils.php:
|
208 |
msgid ""
|
209 |
"WPMU DEV Dashboard will be required for this action. Please visit <a "
|
210 |
"href=\"%s\">here</a> and install the WPMU DEV Dashboard"
|
211 |
msgstr ""
|
212 |
|
213 |
-
#: app/behavior/utils.php:
|
214 |
#: app/module/audit/view/table.php:86 app/module/audit/view/table.php:144
|
215 |
#: free/utils.php:174 free/utils.php:183
|
216 |
msgid "Guest"
|
217 |
msgstr ""
|
218 |
|
219 |
-
#: app/behavior/utils.php:
|
220 |
msgid "WordPress Core Integrity"
|
221 |
msgstr ""
|
222 |
|
223 |
-
#: app/behavior/utils.php:
|
224 |
msgid "Plugins & Themes vulnerability"
|
225 |
msgstr ""
|
226 |
|
227 |
-
#: app/behavior/utils.php:
|
228 |
#: app/module/scan/view/layouts/layout.php:70
|
229 |
#: app/module/scan/view/setting-free.php:52 app/module/scan/view/setting.php:43
|
230 |
-
#: app/view/settings.php:98
|
231 |
msgid "Suspicious Code"
|
232 |
msgstr ""
|
233 |
|
234 |
-
#: app/behavior/utils.php:
|
|
|
|
|
|
|
|
|
|
|
235 |
msgid "Please upgrade to 5.3 or later"
|
236 |
msgstr ""
|
237 |
|
238 |
-
#: app/controller/dashboard.php:
|
239 |
msgid "Dashboard"
|
240 |
msgstr ""
|
241 |
|
242 |
-
#: app/controller/dashboard.php:
|
243 |
-
#: app/controller/requirement.php:69 app/module/ip-lockout/view/locked.php:
|
244 |
msgid "Defender"
|
245 |
msgstr ""
|
246 |
|
247 |
-
#: app/controller/dashboard.php:
|
248 |
msgid "QUICK SETUP"
|
249 |
msgstr ""
|
250 |
|
251 |
-
#: app/controller/dashboard.php:
|
252 |
msgid "Skip"
|
253 |
msgstr ""
|
254 |
|
255 |
-
#: app/controller/dashboard.php:
|
256 |
msgid "Activating File Scanning..."
|
257 |
msgstr ""
|
258 |
|
259 |
-
#: app/controller/dashboard.php:
|
260 |
msgid "Activating Audit Module..."
|
261 |
msgstr ""
|
262 |
|
263 |
-
#: app/controller/dashboard.php:
|
264 |
msgid "Activating IP Lockouts Module..."
|
265 |
msgstr ""
|
266 |
|
267 |
-
#: app/controller/dashboard.php:
|
268 |
msgid "Activating Blacklist Monitoring..."
|
269 |
msgstr ""
|
270 |
|
@@ -304,6 +309,244 @@ msgstr ""
|
|
304 |
msgid "Defender%s"
|
305 |
msgstr ""
|
306 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
#: app/module/audit/behavior/audit-free.php:25
|
308 |
#: app/module/audit/behavior/audit.php:38 app/view/activator.php:35
|
309 |
msgid ""
|
@@ -324,11 +567,6 @@ msgstr ""
|
|
324 |
msgid "Please hold on, Defender will update Audit information soon..."
|
325 |
msgstr ""
|
326 |
|
327 |
-
#: app/module/audit/behavior/audit.php:43 app/module/audit/view/new.php:15
|
328 |
-
#: app/module/ip-lockout/behavior/widget.php:37
|
329 |
-
msgid "Activate"
|
330 |
-
msgstr ""
|
331 |
-
|
332 |
#: app/module/audit/component/audit-api.php:57
|
333 |
#: app/module/audit/component/audit-api.php:89
|
334 |
msgid ""
|
@@ -873,7 +1111,7 @@ msgstr ""
|
|
873 |
#: app/module/scan/view/layouts/layout.php:131
|
874 |
#: app/module/scan/view/layouts/layout.php:146
|
875 |
#: app/module/scan/view/setting-free.php:3 app/module/scan/view/setting.php:3
|
876 |
-
#: app/view/settings.php:6 free/main-activator.php:
|
877 |
msgid "Settings"
|
878 |
msgstr ""
|
879 |
|
@@ -1015,17 +1253,6 @@ msgstr ""
|
|
1015 |
msgid "User"
|
1016 |
msgstr ""
|
1017 |
|
1018 |
-
#: app/module/audit/controller/main.php:143
|
1019 |
-
#: app/module/ip-lockout/controller/main.php:90
|
1020 |
-
msgid "Never"
|
1021 |
-
msgstr ""
|
1022 |
-
|
1023 |
-
#: app/module/audit/controller/main.php:196
|
1024 |
-
#: app/module/ip-lockout/controller/main.php:656
|
1025 |
-
#: app/module/scan/controller/main.php:306
|
1026 |
-
msgid "Your settings have been updated."
|
1027 |
-
msgstr ""
|
1028 |
-
|
1029 |
#: app/module/audit/controller/main.php:331
|
1030 |
msgid "Hi {USER_NAME},"
|
1031 |
msgstr ""
|
@@ -1132,7 +1359,7 @@ msgstr ""
|
|
1132 |
msgid "<a href=\"%s\">Configure reporting preferences</a>"
|
1133 |
msgstr ""
|
1134 |
|
1135 |
-
#: app/module/audit/view/free.php:9 free/main-activator.php:
|
1136 |
msgid "Upgrade"
|
1137 |
msgstr ""
|
1138 |
|
@@ -1345,14 +1572,6 @@ msgstr ""
|
|
1345 |
msgid "Update Settings"
|
1346 |
msgstr ""
|
1347 |
|
1348 |
-
#: app/module/audit/view/report.php:68 app/module/scan/controller/main.php:531
|
1349 |
-
msgid "Cancel"
|
1350 |
-
msgstr ""
|
1351 |
-
|
1352 |
-
#: app/module/audit/view/settings.php:10
|
1353 |
-
msgid "Deactivate"
|
1354 |
-
msgstr ""
|
1355 |
-
|
1356 |
#: app/module/audit/view/settings.php:13
|
1357 |
msgid "If you no longer want to use this feature you can turn it off at any time."
|
1358 |
msgstr ""
|
@@ -1431,14 +1650,14 @@ msgid "Audit log reports are disabled"
|
|
1431 |
msgstr ""
|
1432 |
|
1433 |
#: app/module/hardener/behavior/widget.php:19
|
1434 |
-
#: app/module/hardener/controller/main.php:
|
1435 |
#: app/module/hardener/view/layouts/layout.php:3
|
1436 |
msgid "Security Tweaks"
|
1437 |
msgstr ""
|
1438 |
|
1439 |
#: app/module/hardener/behavior/widget.php:34
|
1440 |
msgid ""
|
1441 |
-
"
|
1442 |
" defense against hackers and bots."
|
1443 |
msgstr ""
|
1444 |
|
@@ -1485,7 +1704,7 @@ msgstr ""
|
|
1485 |
#: app/module/hardener/component/servers/apache-service.php:104
|
1486 |
#: app/module/hardener/component/servers/apache-service.php:108
|
1487 |
#: app/module/hardener/component/servers/apache-service.php:158
|
1488 |
-
#: app/module/hardener/component/servers/apache-service.php:
|
1489 |
msgid "The file %s is not writeable"
|
1490 |
msgstr ""
|
1491 |
|
@@ -1538,6 +1757,14 @@ msgstr ""
|
|
1538 |
msgid "Disable the file editor"
|
1539 |
msgstr ""
|
1540 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1541 |
#: app/module/hardener/component/disable-trackback.php:28
|
1542 |
#: app/module/hardener/view/rules/disable-trackback.php:8
|
1543 |
msgid "Disable trackbacks and pingbacks"
|
@@ -1552,6 +1779,20 @@ msgstr ""
|
|
1552 |
msgid "Hide error reporting"
|
1553 |
msgstr ""
|
1554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1555 |
#: app/module/hardener/component/php-version.php:30
|
1556 |
#: app/module/hardener/view/rules/php-version.php:8
|
1557 |
msgid "Update PHP to latest version"
|
@@ -1576,12 +1817,12 @@ msgstr ""
|
|
1576 |
msgid "Prevent Information Disclosure"
|
1577 |
msgstr ""
|
1578 |
|
1579 |
-
#: app/module/hardener/component/security-key.php:
|
1580 |
#: app/module/hardener/view/rules/security-key.php:8
|
1581 |
msgid "Update old security keys"
|
1582 |
msgstr ""
|
1583 |
|
1584 |
-
#: app/module/hardener/component/security-key.php:
|
1585 |
msgid ""
|
1586 |
"All key salts have been regenerated. You will now need to <a "
|
1587 |
"href=\"%s\"><strong>re-login</strong></a>.<br/>This will auto reload after "
|
@@ -1597,25 +1838,29 @@ msgstr ""
|
|
1597 |
msgid "Update WordPress to latest version"
|
1598 |
msgstr ""
|
1599 |
|
1600 |
-
#: app/module/hardener/controller/main.php:
|
1601 |
msgid "Security tweak successfully restored."
|
1602 |
msgstr ""
|
1603 |
|
1604 |
-
#: app/module/hardener/controller/main.php:
|
1605 |
msgid "Security tweak successfully ignored."
|
1606 |
msgstr ""
|
1607 |
|
1608 |
-
#: app/module/hardener/controller/main.php:
|
1609 |
msgid "Security tweak successfully reverted."
|
1610 |
msgstr ""
|
1611 |
|
1612 |
-
#: app/module/hardener/controller/main.php:
|
1613 |
msgid "Security tweak successfully resolved."
|
1614 |
msgstr ""
|
1615 |
|
|
|
|
|
|
|
|
|
1616 |
#: app/module/hardener/rule.php:111
|
1617 |
-
#: app/module/scan/behavior/core-result.php:
|
1618 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
1619 |
#: app/module/scan/behavior/pro/vuln-result.php:156
|
1620 |
#: app/module/scan/component/result-table.php:199
|
1621 |
msgid "Ignore"
|
@@ -1705,6 +1950,7 @@ msgstr ""
|
|
1705 |
#: app/module/hardener/view/rules/disable-file-editor.php:11
|
1706 |
#: app/module/hardener/view/rules/disable-trackback.php:11
|
1707 |
#: app/module/hardener/view/rules/hide-error.php:11
|
|
|
1708 |
#: app/module/hardener/view/rules/php-version.php:11
|
1709 |
#: app/module/hardener/view/rules/prevent-php-executed.php:11
|
1710 |
#: app/module/hardener/view/rules/protect-information.php:11
|
@@ -1728,6 +1974,7 @@ msgstr ""
|
|
1728 |
#: app/module/hardener/view/rules/disable-file-editor.php:16
|
1729 |
#: app/module/hardener/view/rules/disable-trackback.php:16
|
1730 |
#: app/module/hardener/view/rules/hide-error.php:16
|
|
|
1731 |
#: app/module/hardener/view/rules/php-version.php:34
|
1732 |
#: app/module/hardener/view/rules/prevent-php-executed.php:16
|
1733 |
#: app/module/hardener/view/rules/protect-information.php:16
|
@@ -1750,6 +1997,7 @@ msgstr ""
|
|
1750 |
|
1751 |
#: app/module/hardener/view/rules/change-admin.php:34
|
1752 |
#: app/module/hardener/view/rules/db-prefix.php:37
|
|
|
1753 |
#: app/module/hardener/view/rules/security-key.php:31
|
1754 |
#: app/module/scan/behavior/pro/vuln-result.php:162
|
1755 |
#: app/module/scan/behavior/pro/vuln-result.php:166
|
@@ -1793,7 +2041,8 @@ msgstr ""
|
|
1793 |
|
1794 |
#: app/module/hardener/view/rules/disable-file-editor.php:26
|
1795 |
#: app/module/hardener/view/rules/disable-trackback.php:26
|
1796 |
-
#: app/module/hardener/view/rules/
|
|
|
1797 |
#: app/module/hardener/view/rules/protect-information.php:26
|
1798 |
msgid "Revert"
|
1799 |
msgstr ""
|
@@ -1864,6 +2113,20 @@ msgid ""
|
|
1864 |
"your hosting provider and ask them to set WP_DEBUG to false."
|
1865 |
msgstr ""
|
1866 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1867 |
#: app/module/hardener/view/rules/php-version.php:14
|
1868 |
msgid ""
|
1869 |
"PHP versions older than 5.6 are no longer supported. For security and "
|
@@ -1903,17 +2166,25 @@ msgid ""
|
|
1903 |
"direct PHP execution in directories that don't require it."
|
1904 |
msgstr ""
|
1905 |
|
1906 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1907 |
msgid "PHP execution is locked down."
|
1908 |
msgstr ""
|
1909 |
|
1910 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1911 |
#: app/module/hardener/view/rules/protect-information.php:42
|
1912 |
msgid "Server Type:"
|
1913 |
msgstr ""
|
1914 |
|
1915 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1916 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1917 |
#: app/module/hardener/view/rules/protect-information.php:54
|
1918 |
#: app/module/hardener/view/rules/protect-information.php:66
|
1919 |
msgid ""
|
@@ -1921,76 +2192,78 @@ msgid ""
|
|
1921 |
"down the files and folders inside."
|
1922 |
msgstr ""
|
1923 |
|
1924 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1925 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1926 |
-
msgid ""
|
1927 |
-
"File paths to ignore in the /wp-content directory (each in a new line). The "
|
1928 |
-
"file index.php is not allowed"
|
1929 |
-
msgstr ""
|
1930 |
-
|
1931 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:78
|
1932 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:96
|
1933 |
#: app/module/hardener/view/rules/protect-information.php:61
|
1934 |
#: app/module/hardener/view/rules/protect-information.php:73
|
1935 |
msgid "Add .htaccess file"
|
1936 |
msgstr ""
|
1937 |
|
1938 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1939 |
#: app/module/hardener/view/rules/protect-information.php:105
|
1940 |
msgid "For NGINX servers:"
|
1941 |
msgstr ""
|
1942 |
|
1943 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1944 |
-
msgid ""
|
1945 |
-
"Input the file paths to ignore in the /wp-content directory (each in a new "
|
1946 |
-
"line). The file index.php is not allowed"
|
1947 |
-
msgstr ""
|
1948 |
-
|
1949 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:127
|
1950 |
#: app/module/hardener/view/rules/protect-information.php:108
|
1951 |
msgid ""
|
1952 |
"Copy the generated code into your site specific .conf file usually located "
|
1953 |
"in a subdirectory under /etc/nginx/... or /usr/local/nginx/conf/..."
|
1954 |
msgstr ""
|
1955 |
|
1956 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1957 |
#: app/module/hardener/view/rules/protect-information.php:111
|
1958 |
msgid ""
|
1959 |
"Add the code above inside the <strong>server</strong> section in the file, "
|
1960 |
"right before the php location block. Looks something like:"
|
1961 |
msgstr ""
|
1962 |
|
1963 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1964 |
#: app/module/hardener/view/rules/protect-information.php:115
|
1965 |
msgid "Reload NGINX."
|
1966 |
msgstr ""
|
1967 |
|
1968 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1969 |
#: app/module/hardener/view/rules/protect-information.php:118
|
1970 |
msgid ""
|
1971 |
"Still having trouble? <a target='_blank' href=\"%s\">Open a support "
|
1972 |
"ticket</a>."
|
1973 |
msgstr ""
|
1974 |
|
1975 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1976 |
#: app/module/hardener/view/rules/protect-information.php:124
|
1977 |
msgid "For IIS servers, <a href=\"%s\">visit Microsoft TechNet</a>"
|
1978 |
msgstr ""
|
1979 |
|
1980 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1981 |
msgid ""
|
1982 |
"We will place <strong>web.config</strong> file into the uploads folder to "
|
1983 |
"lock down the files and folders inside."
|
1984 |
msgstr ""
|
1985 |
|
1986 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1987 |
msgid "For more information, please <a href=\"%s\">visit Microsoft TechNet</a>"
|
1988 |
msgstr ""
|
1989 |
|
1990 |
-
#: app/module/hardener/view/rules/prevent-php-executed.php:
|
1991 |
msgid "Add web.config file"
|
1992 |
msgstr ""
|
1993 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1994 |
#: app/module/hardener/view/rules/protect-information.php:13
|
1995 |
msgid ""
|
1996 |
"Often servers are incorrectly configured, and can allow an attacker to get "
|
@@ -2093,12 +2366,10 @@ msgid "Last lockout"
|
|
2093 |
msgstr ""
|
2094 |
|
2095 |
#: app/module/ip-lockout/behavior/widget.php:51
|
2096 |
-
#: app/module/ip-lockout/view/layouts/layout.php:34
|
2097 |
msgid "Login lockouts this week"
|
2098 |
msgstr ""
|
2099 |
|
2100 |
#: app/module/ip-lockout/behavior/widget.php:57
|
2101 |
-
#: app/module/ip-lockout/view/layouts/layout.php:40
|
2102 |
msgid "404 lockouts this week"
|
2103 |
msgstr ""
|
2104 |
|
@@ -2114,23 +2385,23 @@ msgstr ""
|
|
2114 |
msgid "Lockout notifications are disabled"
|
2115 |
msgstr ""
|
2116 |
|
2117 |
-
#: app/module/ip-lockout/component/login-protection-api.php:
|
2118 |
-
#: app/module/ip-lockout/controller/main.php:
|
2119 |
-
#: app/module/ip-lockout/controller/main.php:
|
2120 |
msgid ""
|
2121 |
"You have been locked out by the administrator for attempting to login with "
|
2122 |
"a banned username"
|
2123 |
msgstr ""
|
2124 |
|
2125 |
-
#: app/module/ip-lockout/component/login-protection-api.php:
|
2126 |
msgid "Lockout occurred: Attempting to login with a banned username."
|
2127 |
msgstr ""
|
2128 |
|
2129 |
-
#: app/module/ip-lockout/component/login-protection-api.php:
|
2130 |
msgid "Lockout occurred: Too many failed login attempts"
|
2131 |
msgstr ""
|
2132 |
|
2133 |
-
#: app/module/ip-lockout/component/login-protection-api.php:
|
2134 |
msgid "Lockout occurred: Too many 404 requests for %s"
|
2135 |
msgstr ""
|
2136 |
|
@@ -2186,23 +2457,28 @@ msgid "All"
|
|
2186 |
msgstr ""
|
2187 |
|
2188 |
#: app/module/ip-lockout/component/logs-table.php:164
|
2189 |
-
#: app/module/ip-lockout/model/log-model.php:
|
|
|
2190 |
msgid "Failed login attempts"
|
2191 |
msgstr ""
|
2192 |
|
2193 |
#: app/module/ip-lockout/component/logs-table.php:166
|
2194 |
-
#: app/module/ip-lockout/model/log-model.php:
|
|
|
2195 |
msgid "Login lockout"
|
2196 |
msgstr ""
|
2197 |
|
2198 |
#: app/module/ip-lockout/component/logs-table.php:168
|
2199 |
-
#: app/module/ip-lockout/model/log-model.php:
|
2200 |
-
#: app/module/ip-lockout/model/log-model.php:
|
|
|
|
|
2201 |
msgid "404 error"
|
2202 |
msgstr ""
|
2203 |
|
2204 |
#: app/module/ip-lockout/component/logs-table.php:170
|
2205 |
-
#: app/module/ip-lockout/model/log-model.php:
|
|
|
2206 |
msgid "404 lockout"
|
2207 |
msgstr ""
|
2208 |
|
@@ -2224,60 +2500,60 @@ msgstr ""
|
|
2224 |
msgid "%s results"
|
2225 |
msgstr ""
|
2226 |
|
2227 |
-
#: app/module/ip-lockout/controller/main.php:
|
2228 |
msgid "Your logs have been successfully deleted."
|
2229 |
msgstr ""
|
2230 |
|
2231 |
-
#: app/module/ip-lockout/controller/main.php:
|
2232 |
msgid ""
|
2233 |
"IP %s has been added to your blacklist. You can control your blacklist in "
|
2234 |
"<a href=\"%s\">IP Lockouts.</a>"
|
2235 |
msgstr ""
|
2236 |
|
2237 |
-
#: app/module/ip-lockout/controller/main.php:
|
2238 |
msgid "No record found"
|
2239 |
msgstr ""
|
2240 |
|
2241 |
-
#: app/module/ip-lockout/controller/main.php:
|
2242 |
msgid "Demo"
|
2243 |
msgstr ""
|
2244 |
|
2245 |
-
#: app/module/ip-lockout/controller/main.php:
|
2246 |
msgid "404 lockout alert for %s"
|
2247 |
msgstr ""
|
2248 |
|
2249 |
-
#: app/module/ip-lockout/controller/main.php:
|
2250 |
msgid "Login lockout alert for %s"
|
2251 |
msgstr ""
|
2252 |
|
2253 |
-
#: app/module/ip-lockout/controller/main.php:
|
2254 |
msgid "Failed login attempt with username %s"
|
2255 |
msgstr ""
|
2256 |
|
2257 |
-
#: app/module/ip-lockout/controller/main.php:
|
2258 |
-
#: app/module/ip-lockout/controller/main.php:
|
2259 |
msgid "%d login attempts remaining"
|
2260 |
msgstr ""
|
2261 |
|
2262 |
-
#: app/module/ip-lockout/controller/main.php:
|
2263 |
msgid ""
|
2264 |
"Your settings have been updated, however some IPs were removed because "
|
2265 |
"invalid format, or you blacklist yourself"
|
2266 |
msgstr ""
|
2267 |
|
2268 |
-
#: app/module/ip-lockout/controller/main.php:
|
2269 |
msgid "Login Protection has been activated."
|
2270 |
msgstr ""
|
2271 |
|
2272 |
-
#: app/module/ip-lockout/controller/main.php:
|
2273 |
msgid "Login Protection has been deactivated."
|
2274 |
msgstr ""
|
2275 |
|
2276 |
-
#: app/module/ip-lockout/controller/main.php:
|
2277 |
msgid "404 Detection has been activated."
|
2278 |
msgstr ""
|
2279 |
|
2280 |
-
#: app/module/ip-lockout/controller/main.php:
|
2281 |
msgid "404 Detection has been deactivated."
|
2282 |
msgstr ""
|
2283 |
|
@@ -2299,7 +2575,12 @@ msgstr ""
|
|
2299 |
msgid "Your whitelist/blacklist has been successfully imported."
|
2300 |
msgstr ""
|
2301 |
|
2302 |
-
#: app/module/ip-lockout/
|
|
|
|
|
|
|
|
|
|
|
2303 |
msgid ""
|
2304 |
"Request for file <span class='log-text-table' tooltip='%s'>%s</span> which "
|
2305 |
"doesn't exist"
|
@@ -2399,11 +2680,6 @@ msgid ""
|
|
2399 |
"temporarily block them from accessing your site."
|
2400 |
msgstr ""
|
2401 |
|
2402 |
-
#: app/module/ip-lockout/view/detect-404/disabled.php:16
|
2403 |
-
#: app/module/ip-lockout/view/login-lockouts/disabled.php:18
|
2404 |
-
msgid "Enable"
|
2405 |
-
msgstr ""
|
2406 |
-
|
2407 |
#: app/module/ip-lockout/view/detect-404/enabled.php:7
|
2408 |
msgid "Deactivate 404 Detection"
|
2409 |
msgstr ""
|
@@ -2543,7 +2819,7 @@ msgstr ""
|
|
2543 |
#: app/module/ip-lockout/view/emails/login-lockout.php:482
|
2544 |
#: app/module/ip-lockout/view/emails/login-username-ban.php:481
|
2545 |
#: app/module/ip-lockout/view/emails/report.php:515
|
2546 |
-
#: app/module/ip-lockout/view/locked.php:
|
2547 |
msgid "WP Defender"
|
2548 |
msgstr ""
|
2549 |
|
@@ -2632,7 +2908,15 @@ msgid "Lockouts in the past 24 hours"
|
|
2632 |
msgstr ""
|
2633 |
|
2634 |
#: app/module/ip-lockout/view/layouts/layout.php:21
|
2635 |
-
msgid "Total lockouts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2636 |
msgstr ""
|
2637 |
|
2638 |
#: app/module/ip-lockout/view/layouts/layout.php:54
|
@@ -2672,7 +2956,7 @@ msgstr ""
|
|
2672 |
msgid "IP Blacklist"
|
2673 |
msgstr ""
|
2674 |
|
2675 |
-
#: app/module/ip-lockout/view/locked.php:
|
2676 |
msgid "Powered by"
|
2677 |
msgstr ""
|
2678 |
|
@@ -2732,6 +3016,14 @@ msgid ""
|
|
2732 |
"these are common for bots to try logging in with. One username per line"
|
2733 |
msgstr ""
|
2734 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2735 |
#: app/module/ip-lockout/view/notification/enabled.php:10
|
2736 |
msgid "Send email notifications"
|
2737 |
msgstr ""
|
@@ -2880,66 +3172,75 @@ msgstr ""
|
|
2880 |
msgid "This WordPress core file appears modified"
|
2881 |
msgstr ""
|
2882 |
|
2883 |
-
#: app/module/scan/behavior/core-result.php:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2884 |
msgid "This file can't not remove"
|
2885 |
msgstr ""
|
2886 |
|
2887 |
-
#: app/module/scan/behavior/core-result.php:
|
2888 |
msgid "This file is not resolvable"
|
2889 |
msgstr ""
|
2890 |
|
2891 |
-
#: app/module/scan/behavior/core-result.php:
|
2892 |
msgid ""
|
2893 |
"It seems the %s file is currently using by another process or isn't "
|
2894 |
"writeable."
|
2895 |
msgstr ""
|
2896 |
|
2897 |
-
#: app/module/scan/behavior/core-result.php:
|
2898 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2899 |
#: app/module/scan/behavior/pro/vuln-result.php:109
|
2900 |
msgid "Issue Details"
|
2901 |
msgstr ""
|
2902 |
|
2903 |
-
#: app/module/scan/behavior/core-result.php:
|
2904 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2905 |
msgid "Location"
|
2906 |
msgstr ""
|
2907 |
|
2908 |
-
#: app/module/scan/behavior/core-result.php:
|
2909 |
msgid "Size"
|
2910 |
msgstr ""
|
2911 |
|
2912 |
-
#: app/module/scan/behavior/core-result.php:
|
2913 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2914 |
msgid "Date Added"
|
2915 |
msgstr ""
|
2916 |
|
2917 |
-
#: app/module/scan/behavior/core-result.php:
|
2918 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2919 |
msgid "Delete"
|
2920 |
msgstr ""
|
2921 |
|
2922 |
-
#: app/module/scan/behavior/core-result.php:
|
2923 |
msgid ""
|
2924 |
"This will permanent remove the file/folder with all content, do you want to "
|
2925 |
"do this?"
|
2926 |
msgstr ""
|
2927 |
|
2928 |
-
#: app/module/scan/behavior/core-result.php:
|
2929 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2930 |
msgid "Yes"
|
2931 |
msgstr ""
|
2932 |
|
2933 |
-
#: app/module/scan/behavior/core-result.php:
|
2934 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2935 |
msgid "No"
|
2936 |
msgstr ""
|
2937 |
|
2938 |
-
#: app/module/scan/behavior/core-result.php:
|
2939 |
msgid "Restore to Original"
|
2940 |
msgstr ""
|
2941 |
|
2942 |
-
#: app/module/scan/behavior/core-result.php:
|
2943 |
msgid ""
|
2944 |
"A stray file has been found in your site directory, which your version of "
|
2945 |
"WordPress doesn't need. As far as we can tell, the file is harmless (and "
|
@@ -2948,21 +3249,21 @@ msgid ""
|
|
2948 |
"beforehand"
|
2949 |
msgstr ""
|
2950 |
|
2951 |
-
#: app/module/scan/behavior/core-result.php:
|
2952 |
-
#: app/module/scan/behavior/core-result.php:
|
2953 |
-
#: app/module/scan/behavior/core-result.php:
|
2954 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2955 |
msgid "Pulling source file..."
|
2956 |
msgstr ""
|
2957 |
|
2958 |
-
#: app/module/scan/behavior/core-result.php:
|
2959 |
msgid ""
|
2960 |
"Compare your file with the original file in the WordPress repository. "
|
2961 |
"Pieces highlighted in red will be removed when you patch the file, and "
|
2962 |
"pieces highlighted in green will be added."
|
2963 |
msgstr ""
|
2964 |
|
2965 |
-
#: app/module/scan/behavior/core-result.php:
|
2966 |
msgid ""
|
2967 |
"We found this folder in your WordPress file list. Your current version of "
|
2968 |
"WordPress doesn’t use this folder so it might belong to another "
|
@@ -2971,11 +3272,11 @@ msgid ""
|
|
2971 |
"support team for more information."
|
2972 |
msgstr ""
|
2973 |
|
2974 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2975 |
msgid "Suspicious function found"
|
2976 |
msgstr ""
|
2977 |
|
2978 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2979 |
msgid ""
|
2980 |
" There’s some suspicious looking code in the file %s. If you know the code "
|
2981 |
"is harmless you can ignore this warning. Otherwise, you can choose to "
|
@@ -2983,19 +3284,19 @@ msgid ""
|
|
2983 |
"recommend backing up your website."
|
2984 |
msgstr ""
|
2985 |
|
2986 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2987 |
msgid ""
|
2988 |
"This will permanent delete the whole plugin containing this file, do you "
|
2989 |
"want to do this?"
|
2990 |
msgstr ""
|
2991 |
|
2992 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2993 |
msgid ""
|
2994 |
"This will permanent delete the whole theme containing this file, do you "
|
2995 |
"want to do this?"
|
2996 |
msgstr ""
|
2997 |
|
2998 |
-
#: app/module/scan/behavior/pro/content-result.php:
|
2999 |
msgid "This will permanent delete this file, do you want to do this?"
|
3000 |
msgstr ""
|
3001 |
|
@@ -3121,7 +3422,7 @@ msgid "Suspicious File"
|
|
3121 |
msgstr ""
|
3122 |
|
3123 |
#: app/module/scan/component/result-table.php:35
|
3124 |
-
#: app/module/scan/controller/main.php:
|
3125 |
msgid "Issue"
|
3126 |
msgstr ""
|
3127 |
|
@@ -3182,81 +3483,81 @@ msgstr ""
|
|
3182 |
msgid "Update Theme"
|
3183 |
msgstr ""
|
3184 |
|
3185 |
-
#: app/module/scan/controller/main.php:
|
3186 |
-
#: app/module/scan/controller/main.php:
|
3187 |
msgid "The suspicious file has been successfully ignored."
|
3188 |
msgid_plural "The suspicious files have been successfully ignored."
|
3189 |
msgstr[0] ""
|
3190 |
msgstr[1] ""
|
3191 |
|
3192 |
-
#: app/module/scan/controller/main.php:
|
3193 |
-
#: app/module/scan/controller/main.php:
|
3194 |
msgid "The suspicious file has been successfully restored."
|
3195 |
msgid_plural "The suspicious files have been successfully restored."
|
3196 |
msgstr[0] ""
|
3197 |
msgstr[1] ""
|
3198 |
|
3199 |
-
#: app/module/scan/controller/main.php:
|
3200 |
msgid "The suspicious files has been successfully deleted."
|
3201 |
msgid_plural "The suspicious files have been successfully deleted."
|
3202 |
msgstr[0] ""
|
3203 |
msgstr[1] ""
|
3204 |
|
3205 |
-
#: app/module/scan/controller/main.php:
|
3206 |
msgid "No item has been deleted"
|
3207 |
msgstr ""
|
3208 |
|
3209 |
-
#: app/module/scan/controller/main.php:
|
3210 |
msgid "The suspicious files has been successfully resolved."
|
3211 |
msgid_plural "The suspicious files have been successfully resolved."
|
3212 |
msgstr[0] ""
|
3213 |
msgstr[1] ""
|
3214 |
|
3215 |
-
#: app/module/scan/controller/main.php:
|
3216 |
msgid "No item has been resolved"
|
3217 |
msgstr ""
|
3218 |
|
3219 |
-
#: app/module/scan/controller/main.php:
|
3220 |
msgid "This item has been resolved."
|
3221 |
msgstr ""
|
3222 |
|
3223 |
-
#: app/module/scan/controller/main.php:
|
3224 |
msgid "Please try again!"
|
3225 |
msgstr ""
|
3226 |
|
3227 |
-
#: app/module/scan/controller/main.php:
|
3228 |
-
#: app/module/scan/controller/main.php:
|
3229 |
-
#: app/module/scan/controller/main.php:
|
3230 |
-
#: app/module/scan/controller/main.php:
|
3231 |
msgid "The item doesn't exist!"
|
3232 |
msgstr ""
|
3233 |
|
3234 |
-
#: app/module/scan/controller/main.php:
|
3235 |
msgid "This item has been permanent removed."
|
3236 |
msgstr ""
|
3237 |
|
3238 |
-
#: app/module/scan/controller/main.php:
|
3239 |
#: app/module/scan/view/layouts/layout.php:5
|
3240 |
#: app/module/scan/view/scanning.php:6 app/view/activator-free.php:13
|
3241 |
#: app/view/activator.php:13
|
3242 |
msgid "File Scanning"
|
3243 |
msgstr ""
|
3244 |
|
3245 |
-
#: app/module/scan/controller/main.php:
|
3246 |
msgid "Scan In Progress"
|
3247 |
msgstr ""
|
3248 |
|
3249 |
-
#: app/module/scan/controller/main.php:
|
3250 |
msgid ""
|
3251 |
"Your code is currently clean! There were no issues found during the last "
|
3252 |
"scan, though you can always perform a new scan anytime."
|
3253 |
msgstr ""
|
3254 |
|
3255 |
-
#: app/module/scan/controller/main.php:
|
3256 |
msgid "File"
|
3257 |
msgstr ""
|
3258 |
|
3259 |
-
#: app/module/scan/controller/main.php:
|
3260 |
msgid "Let’s get your site patched up."
|
3261 |
msgstr ""
|
3262 |
|
@@ -3738,18 +4039,18 @@ msgid ""
|
|
3738 |
"this email."
|
3739 |
msgstr ""
|
3740 |
|
3741 |
-
#: free/main-activator.php:
|
3742 |
msgid "Get Members!"
|
3743 |
msgstr ""
|
3744 |
|
3745 |
-
#: free/main-activator.php:
|
3746 |
msgid ""
|
3747 |
"%s, you now have access to Defender's pro features but you still have the "
|
3748 |
"free version installed. Let's upgrade Defender and unlock all those juicy "
|
3749 |
"features! %s"
|
3750 |
msgstr ""
|
3751 |
|
3752 |
-
#: free/main-activator.php:
|
3753 |
msgid "<br/>Something went wrong. Please try again later!"
|
3754 |
msgstr ""
|
3755 |
|
@@ -3789,7 +4090,7 @@ msgstr ""
|
|
3789 |
msgid "Rate %s"
|
3790 |
msgstr ""
|
3791 |
|
3792 |
-
#: main-activator.php:
|
3793 |
msgid ""
|
3794 |
"We noticed you have both the free and pro versions of Defender installed, "
|
3795 |
"so we've automatically deactivated the free version for you."
|
@@ -3820,4 +4121,10 @@ msgstr ""
|
|
3820 |
|
3821 |
#. Author URI of the plugin/theme
|
3822 |
msgid "http://premium.wpmudev.org/"
|
|
|
|
|
|
|
|
|
|
|
|
|
3823 |
msgstr ""
|
2 |
# This file is distributed under the GNU General Public License (Version 2 - GPLv2).
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: WP Defender Pro 1.7\n"
|
6 |
"Report-Msgid-Bugs-To: https://wpmudev.org\n"
|
7 |
+
"POT-Creation-Date: 2017-08-17 04:38:03+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=utf-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
152 |
msgstr ""
|
153 |
|
154 |
#: app/behavior/report-free.php:129 app/behavior/report.php:224
|
155 |
+
#: app/behavior/utils.php:663 free/utils.php:516
|
156 |
msgid "daily"
|
157 |
msgstr ""
|
158 |
|
159 |
#: app/behavior/report-free.php:132 app/behavior/report.php:227
|
160 |
+
#: app/behavior/utils.php:666 free/utils.php:519
|
161 |
msgid "weekly"
|
162 |
msgstr ""
|
163 |
|
164 |
#: app/behavior/report-free.php:135 app/behavior/report.php:230
|
165 |
+
#: app/behavior/utils.php:669 free/utils.php:522
|
166 |
msgid "monthly"
|
167 |
msgstr ""
|
168 |
|
204 |
msgid "To activate this report you must first enable the Audit Logging module."
|
205 |
msgstr ""
|
206 |
|
207 |
+
#: app/behavior/utils.php:76 free/utils.php:77
|
208 |
msgid ""
|
209 |
"WPMU DEV Dashboard will be required for this action. Please visit <a "
|
210 |
"href=\"%s\">here</a> and install the WPMU DEV Dashboard"
|
211 |
msgstr ""
|
212 |
|
213 |
+
#: app/behavior/utils.php:173 app/behavior/utils.php:182
|
214 |
#: app/module/audit/view/table.php:86 app/module/audit/view/table.php:144
|
215 |
#: free/utils.php:174 free/utils.php:183
|
216 |
msgid "Guest"
|
217 |
msgstr ""
|
218 |
|
219 |
+
#: app/behavior/utils.php:550
|
220 |
msgid "WordPress Core Integrity"
|
221 |
msgstr ""
|
222 |
|
223 |
+
#: app/behavior/utils.php:551
|
224 |
msgid "Plugins & Themes vulnerability"
|
225 |
msgstr ""
|
226 |
|
227 |
+
#: app/behavior/utils.php:552 app/module/scan/behavior/scan.php:145
|
228 |
#: app/module/scan/view/layouts/layout.php:70
|
229 |
#: app/module/scan/view/setting-free.php:52 app/module/scan/view/setting.php:43
|
230 |
+
#: app/view/settings.php:98
|
231 |
msgid "Suspicious Code"
|
232 |
msgstr ""
|
233 |
|
234 |
+
#: app/behavior/utils.php:557 app/module/audit/controller/main.php:143
|
235 |
+
#: app/module/ip-lockout/controller/main.php:92
|
236 |
+
msgid "Never"
|
237 |
+
msgstr ""
|
238 |
+
|
239 |
+
#: app/behavior/utils.php:646 free/utils.php:499
|
240 |
msgid "Please upgrade to 5.3 or later"
|
241 |
msgstr ""
|
242 |
|
243 |
+
#: app/controller/dashboard.php:60 app/view/dashboard.php:4
|
244 |
msgid "Dashboard"
|
245 |
msgstr ""
|
246 |
|
247 |
+
#: app/controller/dashboard.php:306 app/controller/dashboard.php:308
|
248 |
+
#: app/controller/requirement.php:69 app/module/ip-lockout/view/locked.php:75
|
249 |
msgid "Defender"
|
250 |
msgstr ""
|
251 |
|
252 |
+
#: app/controller/dashboard.php:340
|
253 |
msgid "QUICK SETUP"
|
254 |
msgstr ""
|
255 |
|
256 |
+
#: app/controller/dashboard.php:340
|
257 |
msgid "Skip"
|
258 |
msgstr ""
|
259 |
|
260 |
+
#: app/controller/dashboard.php:341
|
261 |
msgid "Activating File Scanning..."
|
262 |
msgstr ""
|
263 |
|
264 |
+
#: app/controller/dashboard.php:342
|
265 |
msgid "Activating Audit Module..."
|
266 |
msgstr ""
|
267 |
|
268 |
+
#: app/controller/dashboard.php:343
|
269 |
msgid "Activating IP Lockouts Module..."
|
270 |
msgstr ""
|
271 |
|
272 |
+
#: app/controller/dashboard.php:344
|
273 |
msgid "Activating Blacklist Monitoring..."
|
274 |
msgstr ""
|
275 |
|
309 |
msgid "Defender%s"
|
310 |
msgstr ""
|
311 |
|
312 |
+
#: app/module/advanced-tools/controller/main.php:58
|
313 |
+
msgid ""
|
314 |
+
"You enabled Jetpack WordPress.com login, so Defender will disable the 2 "
|
315 |
+
"factors login for avoiding conflict"
|
316 |
+
msgstr ""
|
317 |
+
|
318 |
+
#: app/module/advanced-tools/controller/main.php:61
|
319 |
+
msgid ""
|
320 |
+
"You enabled the plugin Theme My Login, so Defender will disable the 2 "
|
321 |
+
"factors login for avoiding conflict"
|
322 |
+
msgstr ""
|
323 |
+
|
324 |
+
#: app/module/advanced-tools/controller/main.php:135
|
325 |
+
msgid "2 Factor"
|
326 |
+
msgstr ""
|
327 |
+
|
328 |
+
#: app/module/advanced-tools/controller/main.php:158
|
329 |
+
msgid "Your token is invalid"
|
330 |
+
msgstr ""
|
331 |
+
|
332 |
+
#: app/module/advanced-tools/controller/main.php:170
|
333 |
+
msgid "Your code has been sent to your email."
|
334 |
+
msgstr ""
|
335 |
+
|
336 |
+
#: app/module/advanced-tools/controller/main.php:214
|
337 |
+
msgid "Please input a valid OTP code"
|
338 |
+
msgstr ""
|
339 |
+
|
340 |
+
#: app/module/advanced-tools/controller/main.php:228
|
341 |
+
msgid "Your OTP code is incorrect. Please try again."
|
342 |
+
msgstr ""
|
343 |
+
|
344 |
+
#: app/module/advanced-tools/controller/main.php:289
|
345 |
+
msgid "Some error happen"
|
346 |
+
msgstr ""
|
347 |
+
|
348 |
+
#: app/module/advanced-tools/controller/main.php:326
|
349 |
+
msgid "Whoops, the passcode you entered was incorrect or expired."
|
350 |
+
msgstr ""
|
351 |
+
|
352 |
+
#: app/module/advanced-tools/controller/main.php:392
|
353 |
+
#: app/module/advanced-tools/view/layouts/layout.php:5
|
354 |
+
msgid "Advanced Tools"
|
355 |
+
msgstr ""
|
356 |
+
|
357 |
+
#: app/module/advanced-tools/controller/main.php:455
|
358 |
+
#: app/module/audit/controller/main.php:196
|
359 |
+
#: app/module/ip-lockout/controller/main.php:652
|
360 |
+
#: app/module/scan/controller/main.php:305
|
361 |
+
msgid "Your settings have been updated."
|
362 |
+
msgstr ""
|
363 |
+
|
364 |
+
#: app/module/advanced-tools/view/disabled.php:4
|
365 |
+
#: app/module/advanced-tools/view/layouts/layout.php:13
|
366 |
+
#: app/module/advanced-tools/view/layouts/layout.php:20
|
367 |
+
#: app/module/advanced-tools/view/login/disabled.php:6
|
368 |
+
#: app/module/advanced-tools/view/login/enabled.php:6
|
369 |
+
#: app/module/advanced-tools/view/main.php:4
|
370 |
+
msgid "2 Factor Authentication"
|
371 |
+
msgstr ""
|
372 |
+
|
373 |
+
#: app/module/advanced-tools/view/disabled.php:10
|
374 |
+
msgid ""
|
375 |
+
"Beef up your website’s security with 2-Step verification. Protect your user "
|
376 |
+
"accounts by requiring a second passcode sent to users phones in order to "
|
377 |
+
"get past your login screen - the best protection against brute force "
|
378 |
+
"attacks."
|
379 |
+
msgstr ""
|
380 |
+
|
381 |
+
#: app/module/advanced-tools/view/disabled.php:19
|
382 |
+
#: app/module/audit/behavior/audit.php:43 app/module/audit/view/new.php:15
|
383 |
+
#: app/module/ip-lockout/behavior/widget.php:37
|
384 |
+
msgid "Activate"
|
385 |
+
msgstr ""
|
386 |
+
|
387 |
+
#: app/module/advanced-tools/view/login/disabled.php:2
|
388 |
+
#: app/module/advanced-tools/view/login/enabled.php:2
|
389 |
+
msgid "Security"
|
390 |
+
msgstr ""
|
391 |
+
|
392 |
+
#: app/module/advanced-tools/view/login/disabled.php:11
|
393 |
+
#: app/module/ip-lockout/view/detect-404/disabled.php:16
|
394 |
+
#: app/module/ip-lockout/view/login-lockouts/disabled.php:18
|
395 |
+
msgid "Enable"
|
396 |
+
msgstr ""
|
397 |
+
|
398 |
+
#: app/module/advanced-tools/view/login/disabled.php:15
|
399 |
+
#: app/module/advanced-tools/view/login/disabled.php:21
|
400 |
+
msgid "Use the Google Authenticator app to sign in with a separate passcode."
|
401 |
+
msgstr ""
|
402 |
+
|
403 |
+
#: app/module/advanced-tools/view/login/disabled.php:20
|
404 |
+
#: app/module/audit/view/report.php:68 app/module/scan/controller/main.php:530
|
405 |
+
msgid "Cancel"
|
406 |
+
msgstr ""
|
407 |
+
|
408 |
+
#: app/module/advanced-tools/view/login/disabled.php:24
|
409 |
+
msgid "1. Install the Verification app"
|
410 |
+
msgstr ""
|
411 |
+
|
412 |
+
#: app/module/advanced-tools/view/login/disabled.php:27
|
413 |
+
msgid ""
|
414 |
+
"Download and install the Google Authenticator app on your device using the "
|
415 |
+
"links below."
|
416 |
+
msgstr ""
|
417 |
+
|
418 |
+
#: app/module/advanced-tools/view/login/disabled.php:36
|
419 |
+
msgid "2. Scan the barcode"
|
420 |
+
msgstr ""
|
421 |
+
|
422 |
+
#: app/module/advanced-tools/view/login/disabled.php:37
|
423 |
+
msgid ""
|
424 |
+
"Open the Google Authenticator app you just downloaded, tap the “+” symbol "
|
425 |
+
"and then use your phone’s camera to scan the barcode below."
|
426 |
+
msgstr ""
|
427 |
+
|
428 |
+
#: app/module/advanced-tools/view/login/disabled.php:41
|
429 |
+
msgid "3. Enter passcode"
|
430 |
+
msgstr ""
|
431 |
+
|
432 |
+
#: app/module/advanced-tools/view/login/disabled.php:43
|
433 |
+
msgid ""
|
434 |
+
"Enter the 6 digit passcode that is shown on your device into the input "
|
435 |
+
"field below and hit “Verify”."
|
436 |
+
msgstr ""
|
437 |
+
|
438 |
+
#: app/module/advanced-tools/view/login/disabled.php:49
|
439 |
+
msgid "Verify"
|
440 |
+
msgstr ""
|
441 |
+
|
442 |
+
#: app/module/advanced-tools/view/login/enabled.php:9
|
443 |
+
msgid "2 factor authentication is active."
|
444 |
+
msgstr ""
|
445 |
+
|
446 |
+
#: app/module/advanced-tools/view/login/enabled.php:12
|
447 |
+
msgid "Disabled"
|
448 |
+
msgstr ""
|
449 |
+
|
450 |
+
#: app/module/advanced-tools/view/login/enabled.php:17
|
451 |
+
msgid "Fallback email address"
|
452 |
+
msgstr ""
|
453 |
+
|
454 |
+
#: app/module/advanced-tools/view/login/enabled.php:21
|
455 |
+
msgid ""
|
456 |
+
"If you ever lose your device, you can send a fallback passcode to this "
|
457 |
+
"email address."
|
458 |
+
msgstr ""
|
459 |
+
|
460 |
+
#: app/module/advanced-tools/view/login/otp.php:98
|
461 |
+
msgid "https://wordpress.org/"
|
462 |
+
msgstr ""
|
463 |
+
|
464 |
+
#: app/module/advanced-tools/view/login/otp.php:99
|
465 |
+
msgid "Powered by WordPress"
|
466 |
+
msgstr ""
|
467 |
+
|
468 |
+
#: app/module/advanced-tools/view/login/otp.php:224
|
469 |
+
msgid "Enter 6 digit passcode"
|
470 |
+
msgstr ""
|
471 |
+
|
472 |
+
#: app/module/advanced-tools/view/login/otp.php:227
|
473 |
+
msgid "Authenticate"
|
474 |
+
msgstr ""
|
475 |
+
|
476 |
+
#: app/module/advanced-tools/view/login/otp.php:236
|
477 |
+
msgid "Lost your device?"
|
478 |
+
msgstr ""
|
479 |
+
|
480 |
+
#: app/module/advanced-tools/view/main.php:9
|
481 |
+
msgid ""
|
482 |
+
"Configure your 2 factor authentication settings, our recommendations are on "
|
483 |
+
"by default."
|
484 |
+
msgstr ""
|
485 |
+
|
486 |
+
#: app/module/advanced-tools/view/main.php:18
|
487 |
+
msgid "User Roles"
|
488 |
+
msgstr ""
|
489 |
+
|
490 |
+
#: app/module/advanced-tools/view/main.php:20
|
491 |
+
msgid ""
|
492 |
+
"Choose what user roles you want to enable 2 factor authentication for. They "
|
493 |
+
"must then use the Google Authenticator app to login."
|
494 |
+
msgstr ""
|
495 |
+
|
496 |
+
#: app/module/advanced-tools/view/main.php:27
|
497 |
+
msgid "User role"
|
498 |
+
msgstr ""
|
499 |
+
|
500 |
+
#: app/module/advanced-tools/view/main.php:59
|
501 |
+
msgid "Lost Phone"
|
502 |
+
msgstr ""
|
503 |
+
|
504 |
+
#: app/module/advanced-tools/view/main.php:61
|
505 |
+
msgid ""
|
506 |
+
"If a user is unable to access their phone, you can allow an option to send "
|
507 |
+
"the one time password to their registered email."
|
508 |
+
msgstr ""
|
509 |
+
|
510 |
+
#: app/module/advanced-tools/view/main.php:71
|
511 |
+
msgid "Enable lost phone option"
|
512 |
+
msgstr ""
|
513 |
+
|
514 |
+
#: app/module/advanced-tools/view/main.php:76
|
515 |
+
msgid "App Download"
|
516 |
+
msgstr ""
|
517 |
+
|
518 |
+
#: app/module/advanced-tools/view/main.php:78
|
519 |
+
msgid "Need the app? Here’s links to the official Google Authenticator apps."
|
520 |
+
msgstr ""
|
521 |
+
|
522 |
+
#: app/module/advanced-tools/view/main.php:92
|
523 |
+
msgid "Active Users"
|
524 |
+
msgstr ""
|
525 |
+
|
526 |
+
#: app/module/advanced-tools/view/main.php:94
|
527 |
+
msgid ""
|
528 |
+
"Here’s a quick link to see which of your users have enabled 2 step "
|
529 |
+
"verification."
|
530 |
+
msgstr ""
|
531 |
+
|
532 |
+
#: app/module/advanced-tools/view/main.php:98
|
533 |
+
msgid "<a href=\"%s\">View users</a> who have enabled this feature."
|
534 |
+
msgstr ""
|
535 |
+
|
536 |
+
#: app/module/advanced-tools/view/main.php:103
|
537 |
+
#: app/module/advanced-tools/view/main.php:110
|
538 |
+
#: app/module/audit/view/settings.php:10
|
539 |
+
msgid "Deactivate"
|
540 |
+
msgstr ""
|
541 |
+
|
542 |
+
#: app/module/advanced-tools/view/main.php:105
|
543 |
+
msgid "Turn off the 2 factor authentication feature completely."
|
544 |
+
msgstr ""
|
545 |
+
|
546 |
+
#: app/module/advanced-tools/view/main.php:118
|
547 |
+
msgid "SAVE SETTINGS"
|
548 |
+
msgstr ""
|
549 |
+
|
550 |
#: app/module/audit/behavior/audit-free.php:25
|
551 |
#: app/module/audit/behavior/audit.php:38 app/view/activator.php:35
|
552 |
msgid ""
|
567 |
msgid "Please hold on, Defender will update Audit information soon..."
|
568 |
msgstr ""
|
569 |
|
|
|
|
|
|
|
|
|
|
|
570 |
#: app/module/audit/component/audit-api.php:57
|
571 |
#: app/module/audit/component/audit-api.php:89
|
572 |
msgid ""
|
1111 |
#: app/module/scan/view/layouts/layout.php:131
|
1112 |
#: app/module/scan/view/layouts/layout.php:146
|
1113 |
#: app/module/scan/view/setting-free.php:3 app/module/scan/view/setting.php:3
|
1114 |
+
#: app/view/settings.php:6 free/main-activator.php:146 main-activator.php:89
|
1115 |
msgid "Settings"
|
1116 |
msgstr ""
|
1117 |
|
1253 |
msgid "User"
|
1254 |
msgstr ""
|
1255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1256 |
#: app/module/audit/controller/main.php:331
|
1257 |
msgid "Hi {USER_NAME},"
|
1258 |
msgstr ""
|
1359 |
msgid "<a href=\"%s\">Configure reporting preferences</a>"
|
1360 |
msgstr ""
|
1361 |
|
1362 |
+
#: app/module/audit/view/free.php:9 free/main-activator.php:106
|
1363 |
msgid "Upgrade"
|
1364 |
msgstr ""
|
1365 |
|
1572 |
msgid "Update Settings"
|
1573 |
msgstr ""
|
1574 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1575 |
#: app/module/audit/view/settings.php:13
|
1576 |
msgid "If you no longer want to use this feature you can turn it off at any time."
|
1577 |
msgstr ""
|
1650 |
msgstr ""
|
1651 |
|
1652 |
#: app/module/hardener/behavior/widget.php:19
|
1653 |
+
#: app/module/hardener/controller/main.php:159
|
1654 |
#: app/module/hardener/view/layouts/layout.php:3
|
1655 |
msgid "Security Tweaks"
|
1656 |
msgstr ""
|
1657 |
|
1658 |
#: app/module/hardener/behavior/widget.php:34
|
1659 |
msgid ""
|
1660 |
+
"Defender checks for security tweaks you can make to enhance your website’s\n"
|
1661 |
" defense against hackers and bots."
|
1662 |
msgstr ""
|
1663 |
|
1704 |
#: app/module/hardener/component/servers/apache-service.php:104
|
1705 |
#: app/module/hardener/component/servers/apache-service.php:108
|
1706 |
#: app/module/hardener/component/servers/apache-service.php:158
|
1707 |
+
#: app/module/hardener/component/servers/apache-service.php:189
|
1708 |
msgid "The file %s is not writeable"
|
1709 |
msgstr ""
|
1710 |
|
1757 |
msgid "Disable the file editor"
|
1758 |
msgstr ""
|
1759 |
|
1760 |
+
#: app/module/hardener/component/disable-file-editor.php:91
|
1761 |
+
msgid "Sorry, you are not allowed to edit templates for this site."
|
1762 |
+
msgstr ""
|
1763 |
+
|
1764 |
+
#: app/module/hardener/component/disable-file-editor.php:94
|
1765 |
+
msgid "Sorry, you are not allowed to edit plugins for this site."
|
1766 |
+
msgstr ""
|
1767 |
+
|
1768 |
#: app/module/hardener/component/disable-trackback.php:28
|
1769 |
#: app/module/hardener/view/rules/disable-trackback.php:8
|
1770 |
msgid "Disable trackbacks and pingbacks"
|
1779 |
msgid "Hide error reporting"
|
1780 |
msgstr ""
|
1781 |
|
1782 |
+
#: app/module/hardener/component/login-duration.php:38
|
1783 |
+
msgid "Manage Login Duration"
|
1784 |
+
msgstr ""
|
1785 |
+
|
1786 |
+
#: app/module/hardener/component/login-duration.php:94
|
1787 |
+
msgid "Duration can only be a number"
|
1788 |
+
msgstr ""
|
1789 |
+
|
1790 |
+
#: app/module/hardener/component/login-duration.php:190
|
1791 |
+
msgid ""
|
1792 |
+
"Your session has expired because it has been over %d days since your last "
|
1793 |
+
"login. Please log back in to continue."
|
1794 |
+
msgstr ""
|
1795 |
+
|
1796 |
#: app/module/hardener/component/php-version.php:30
|
1797 |
#: app/module/hardener/view/rules/php-version.php:8
|
1798 |
msgid "Update PHP to latest version"
|
1817 |
msgid "Prevent Information Disclosure"
|
1818 |
msgstr ""
|
1819 |
|
1820 |
+
#: app/module/hardener/component/security-key.php:40
|
1821 |
#: app/module/hardener/view/rules/security-key.php:8
|
1822 |
msgid "Update old security keys"
|
1823 |
msgstr ""
|
1824 |
|
1825 |
+
#: app/module/hardener/component/security-key.php:82
|
1826 |
msgid ""
|
1827 |
"All key salts have been regenerated. You will now need to <a "
|
1828 |
"href=\"%s\"><strong>re-login</strong></a>.<br/>This will auto reload after "
|
1838 |
msgid "Update WordPress to latest version"
|
1839 |
msgstr ""
|
1840 |
|
1841 |
+
#: app/module/hardener/controller/main.php:58
|
1842 |
msgid "Security tweak successfully restored."
|
1843 |
msgstr ""
|
1844 |
|
1845 |
+
#: app/module/hardener/controller/main.php:76
|
1846 |
msgid "Security tweak successfully ignored."
|
1847 |
msgstr ""
|
1848 |
|
1849 |
+
#: app/module/hardener/controller/main.php:92
|
1850 |
msgid "Security tweak successfully reverted."
|
1851 |
msgstr ""
|
1852 |
|
1853 |
+
#: app/module/hardener/controller/main.php:118
|
1854 |
msgid "Security tweak successfully resolved."
|
1855 |
msgstr ""
|
1856 |
|
1857 |
+
#: app/module/hardener/controller/main.php:146
|
1858 |
+
msgid "Security tweak successfully updated."
|
1859 |
+
msgstr ""
|
1860 |
+
|
1861 |
#: app/module/hardener/rule.php:111
|
1862 |
+
#: app/module/scan/behavior/core-result.php:189
|
1863 |
+
#: app/module/scan/behavior/pro/content-result.php:106
|
1864 |
#: app/module/scan/behavior/pro/vuln-result.php:156
|
1865 |
#: app/module/scan/component/result-table.php:199
|
1866 |
msgid "Ignore"
|
1950 |
#: app/module/hardener/view/rules/disable-file-editor.php:11
|
1951 |
#: app/module/hardener/view/rules/disable-trackback.php:11
|
1952 |
#: app/module/hardener/view/rules/hide-error.php:11
|
1953 |
+
#: app/module/hardener/view/rules/login-duration.php:11
|
1954 |
#: app/module/hardener/view/rules/php-version.php:11
|
1955 |
#: app/module/hardener/view/rules/prevent-php-executed.php:11
|
1956 |
#: app/module/hardener/view/rules/protect-information.php:11
|
1974 |
#: app/module/hardener/view/rules/disable-file-editor.php:16
|
1975 |
#: app/module/hardener/view/rules/disable-trackback.php:16
|
1976 |
#: app/module/hardener/view/rules/hide-error.php:16
|
1977 |
+
#: app/module/hardener/view/rules/login-duration.php:16
|
1978 |
#: app/module/hardener/view/rules/php-version.php:34
|
1979 |
#: app/module/hardener/view/rules/prevent-php-executed.php:16
|
1980 |
#: app/module/hardener/view/rules/protect-information.php:16
|
1997 |
|
1998 |
#: app/module/hardener/view/rules/change-admin.php:34
|
1999 |
#: app/module/hardener/view/rules/db-prefix.php:37
|
2000 |
+
#: app/module/hardener/view/rules/login-duration.php:44
|
2001 |
#: app/module/hardener/view/rules/security-key.php:31
|
2002 |
#: app/module/scan/behavior/pro/vuln-result.php:162
|
2003 |
#: app/module/scan/behavior/pro/vuln-result.php:166
|
2041 |
|
2042 |
#: app/module/hardener/view/rules/disable-file-editor.php:26
|
2043 |
#: app/module/hardener/view/rules/disable-trackback.php:26
|
2044 |
+
#: app/module/hardener/view/rules/login-duration.php:29
|
2045 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:52
|
2046 |
#: app/module/hardener/view/rules/protect-information.php:26
|
2047 |
msgid "Revert"
|
2048 |
msgstr ""
|
2113 |
"your hosting provider and ask them to set WP_DEBUG to false."
|
2114 |
msgstr ""
|
2115 |
|
2116 |
+
#: app/module/hardener/view/rules/login-duration.php:13
|
2117 |
+
msgid ""
|
2118 |
+
"By default, users who select the 'remember me' option stay logged in for 14 "
|
2119 |
+
"days"
|
2120 |
+
msgstr ""
|
2121 |
+
|
2122 |
+
#: app/module/hardener/view/rules/login-duration.php:35
|
2123 |
+
msgid "Please change the number of days a user can stay logged in"
|
2124 |
+
msgstr ""
|
2125 |
+
|
2126 |
+
#: app/module/hardener/view/rules/login-duration.php:40
|
2127 |
+
msgid "Enter number of days"
|
2128 |
+
msgstr ""
|
2129 |
+
|
2130 |
#: app/module/hardener/view/rules/php-version.php:14
|
2131 |
msgid ""
|
2132 |
"PHP versions older than 5.6 are no longer supported. For security and "
|
2166 |
"direct PHP execution in directories that don't require it."
|
2167 |
msgstr ""
|
2168 |
|
2169 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:23
|
2170 |
msgid "PHP execution is locked down."
|
2171 |
msgstr ""
|
2172 |
|
2173 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:28
|
2174 |
+
msgid " The following file paths have been allowed in the /wp-content directory :"
|
2175 |
+
msgstr ""
|
2176 |
+
|
2177 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:39
|
2178 |
+
msgid "Update .htaccess file"
|
2179 |
+
msgstr ""
|
2180 |
+
|
2181 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:77
|
2182 |
#: app/module/hardener/view/rules/protect-information.php:42
|
2183 |
msgid "Server Type:"
|
2184 |
msgstr ""
|
2185 |
|
2186 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:91
|
2187 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:105
|
2188 |
#: app/module/hardener/view/rules/protect-information.php:54
|
2189 |
#: app/module/hardener/view/rules/protect-information.php:66
|
2190 |
msgid ""
|
2192 |
"down the files and folders inside."
|
2193 |
msgstr ""
|
2194 |
|
2195 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:100
|
2196 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:114
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2197 |
#: app/module/hardener/view/rules/protect-information.php:61
|
2198 |
#: app/module/hardener/view/rules/protect-information.php:73
|
2199 |
msgid "Add .htaccess file"
|
2200 |
msgstr ""
|
2201 |
|
2202 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:138
|
2203 |
#: app/module/hardener/view/rules/protect-information.php:105
|
2204 |
msgid "For NGINX servers:"
|
2205 |
msgstr ""
|
2206 |
|
2207 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:141
|
|
|
|
|
|
|
|
|
|
|
|
|
2208 |
#: app/module/hardener/view/rules/protect-information.php:108
|
2209 |
msgid ""
|
2210 |
"Copy the generated code into your site specific .conf file usually located "
|
2211 |
"in a subdirectory under /etc/nginx/... or /usr/local/nginx/conf/..."
|
2212 |
msgstr ""
|
2213 |
|
2214 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:144
|
2215 |
#: app/module/hardener/view/rules/protect-information.php:111
|
2216 |
msgid ""
|
2217 |
"Add the code above inside the <strong>server</strong> section in the file, "
|
2218 |
"right before the php location block. Looks something like:"
|
2219 |
msgstr ""
|
2220 |
|
2221 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:148
|
2222 |
#: app/module/hardener/view/rules/protect-information.php:115
|
2223 |
msgid "Reload NGINX."
|
2224 |
msgstr ""
|
2225 |
|
2226 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:151
|
2227 |
#: app/module/hardener/view/rules/protect-information.php:118
|
2228 |
msgid ""
|
2229 |
"Still having trouble? <a target='_blank' href=\"%s\">Open a support "
|
2230 |
"ticket</a>."
|
2231 |
msgstr ""
|
2232 |
|
2233 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:161
|
2234 |
#: app/module/hardener/view/rules/protect-information.php:124
|
2235 |
msgid "For IIS servers, <a href=\"%s\">visit Microsoft TechNet</a>"
|
2236 |
msgstr ""
|
2237 |
|
2238 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:166
|
2239 |
msgid ""
|
2240 |
"We will place <strong>web.config</strong> file into the uploads folder to "
|
2241 |
"lock down the files and folders inside."
|
2242 |
msgstr ""
|
2243 |
|
2244 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:169
|
2245 |
msgid "For more information, please <a href=\"%s\">visit Microsoft TechNet</a>"
|
2246 |
msgstr ""
|
2247 |
|
2248 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:177
|
2249 |
msgid "Add web.config file"
|
2250 |
msgstr ""
|
2251 |
|
2252 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:189
|
2253 |
+
msgid "Exceptions"
|
2254 |
+
msgstr ""
|
2255 |
+
|
2256 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:192
|
2257 |
+
msgid ""
|
2258 |
+
"By default Defender will lock down directories WordPress doesn't need to "
|
2259 |
+
"allow PHP execution for. However, if you have specific files you need to "
|
2260 |
+
"allow PHP execution for you can add exceptions. Add file name one per line"
|
2261 |
+
msgstr ""
|
2262 |
+
|
2263 |
+
#: app/module/hardener/view/rules/prevent-php-executed.php:193
|
2264 |
+
msgid "Add Exception"
|
2265 |
+
msgstr ""
|
2266 |
+
|
2267 |
#: app/module/hardener/view/rules/protect-information.php:13
|
2268 |
msgid ""
|
2269 |
"Often servers are incorrectly configured, and can allow an attacker to get "
|
2366 |
msgstr ""
|
2367 |
|
2368 |
#: app/module/ip-lockout/behavior/widget.php:51
|
|
|
2369 |
msgid "Login lockouts this week"
|
2370 |
msgstr ""
|
2371 |
|
2372 |
#: app/module/ip-lockout/behavior/widget.php:57
|
|
|
2373 |
msgid "404 lockouts this week"
|
2374 |
msgstr ""
|
2375 |
|
2385 |
msgid "Lockout notifications are disabled"
|
2386 |
msgstr ""
|
2387 |
|
2388 |
+
#: app/module/ip-lockout/component/login-protection-api.php:62
|
2389 |
+
#: app/module/ip-lockout/controller/main.php:547
|
2390 |
+
#: app/module/ip-lockout/controller/main.php:556
|
2391 |
msgid ""
|
2392 |
"You have been locked out by the administrator for attempting to login with "
|
2393 |
"a banned username"
|
2394 |
msgstr ""
|
2395 |
|
2396 |
+
#: app/module/ip-lockout/component/login-protection-api.php:75
|
2397 |
msgid "Lockout occurred: Attempting to login with a banned username."
|
2398 |
msgstr ""
|
2399 |
|
2400 |
+
#: app/module/ip-lockout/component/login-protection-api.php:77
|
2401 |
msgid "Lockout occurred: Too many failed login attempts"
|
2402 |
msgstr ""
|
2403 |
|
2404 |
+
#: app/module/ip-lockout/component/login-protection-api.php:144
|
2405 |
msgid "Lockout occurred: Too many 404 requests for %s"
|
2406 |
msgstr ""
|
2407 |
|
2457 |
msgstr ""
|
2458 |
|
2459 |
#: app/module/ip-lockout/component/logs-table.php:164
|
2460 |
+
#: app/module/ip-lockout/model/log-model-legacy.php:111
|
2461 |
+
#: app/module/ip-lockout/model/log-model.php:64
|
2462 |
msgid "Failed login attempts"
|
2463 |
msgstr ""
|
2464 |
|
2465 |
#: app/module/ip-lockout/component/logs-table.php:166
|
2466 |
+
#: app/module/ip-lockout/model/log-model-legacy.php:112
|
2467 |
+
#: app/module/ip-lockout/model/log-model.php:65
|
2468 |
msgid "Login lockout"
|
2469 |
msgstr ""
|
2470 |
|
2471 |
#: app/module/ip-lockout/component/logs-table.php:168
|
2472 |
+
#: app/module/ip-lockout/model/log-model-legacy.php:113
|
2473 |
+
#: app/module/ip-lockout/model/log-model-legacy.php:114
|
2474 |
+
#: app/module/ip-lockout/model/log-model.php:66
|
2475 |
+
#: app/module/ip-lockout/model/log-model.php:67
|
2476 |
msgid "404 error"
|
2477 |
msgstr ""
|
2478 |
|
2479 |
#: app/module/ip-lockout/component/logs-table.php:170
|
2480 |
+
#: app/module/ip-lockout/model/log-model-legacy.php:115
|
2481 |
+
#: app/module/ip-lockout/model/log-model.php:68
|
2482 |
msgid "404 lockout"
|
2483 |
msgstr ""
|
2484 |
|
2500 |
msgid "%s results"
|
2501 |
msgstr ""
|
2502 |
|
2503 |
+
#: app/module/ip-lockout/controller/main.php:151
|
2504 |
msgid "Your logs have been successfully deleted."
|
2505 |
msgstr ""
|
2506 |
|
2507 |
+
#: app/module/ip-lockout/controller/main.php:191
|
2508 |
msgid ""
|
2509 |
"IP %s has been added to your blacklist. You can control your blacklist in "
|
2510 |
"<a href=\"%s\">IP Lockouts.</a>"
|
2511 |
msgstr ""
|
2512 |
|
2513 |
+
#: app/module/ip-lockout/controller/main.php:196
|
2514 |
msgid "No record found"
|
2515 |
msgstr ""
|
2516 |
|
2517 |
+
#: app/module/ip-lockout/controller/main.php:221
|
2518 |
msgid "Demo"
|
2519 |
msgstr ""
|
2520 |
|
2521 |
+
#: app/module/ip-lockout/controller/main.php:399
|
2522 |
msgid "404 lockout alert for %s"
|
2523 |
msgstr ""
|
2524 |
|
2525 |
+
#: app/module/ip-lockout/controller/main.php:422
|
2526 |
msgid "Login lockout alert for %s"
|
2527 |
msgstr ""
|
2528 |
|
2529 |
+
#: app/module/ip-lockout/controller/main.php:487
|
2530 |
msgid "Failed login attempt with username %s"
|
2531 |
msgstr ""
|
2532 |
|
2533 |
+
#: app/module/ip-lockout/controller/main.php:549
|
2534 |
+
#: app/module/ip-lockout/controller/main.php:559
|
2535 |
msgid "%d login attempts remaining"
|
2536 |
msgstr ""
|
2537 |
|
2538 |
+
#: app/module/ip-lockout/controller/main.php:648
|
2539 |
msgid ""
|
2540 |
"Your settings have been updated, however some IPs were removed because "
|
2541 |
"invalid format, or you blacklist yourself"
|
2542 |
msgstr ""
|
2543 |
|
2544 |
+
#: app/module/ip-lockout/controller/main.php:659
|
2545 |
msgid "Login Protection has been activated."
|
2546 |
msgstr ""
|
2547 |
|
2548 |
+
#: app/module/ip-lockout/controller/main.php:661
|
2549 |
msgid "Login Protection has been deactivated."
|
2550 |
msgstr ""
|
2551 |
|
2552 |
+
#: app/module/ip-lockout/controller/main.php:666
|
2553 |
msgid "404 Detection has been activated."
|
2554 |
msgstr ""
|
2555 |
|
2556 |
+
#: app/module/ip-lockout/controller/main.php:668
|
2557 |
msgid "404 Detection has been deactivated."
|
2558 |
msgstr ""
|
2559 |
|
2575 |
msgid "Your whitelist/blacklist has been successfully imported."
|
2576 |
msgstr ""
|
2577 |
|
2578 |
+
#: app/module/ip-lockout/controller/main.php:905
|
2579 |
+
msgid "Thanks for your patience. All sets!"
|
2580 |
+
msgstr ""
|
2581 |
+
|
2582 |
+
#: app/module/ip-lockout/model/log-model-legacy.php:79
|
2583 |
+
#: app/module/ip-lockout/model/log-model.php:38
|
2584 |
msgid ""
|
2585 |
"Request for file <span class='log-text-table' tooltip='%s'>%s</span> which "
|
2586 |
"doesn't exist"
|
2680 |
"temporarily block them from accessing your site."
|
2681 |
msgstr ""
|
2682 |
|
|
|
|
|
|
|
|
|
|
|
2683 |
#: app/module/ip-lockout/view/detect-404/enabled.php:7
|
2684 |
msgid "Deactivate 404 Detection"
|
2685 |
msgstr ""
|
2819 |
#: app/module/ip-lockout/view/emails/login-lockout.php:482
|
2820 |
#: app/module/ip-lockout/view/emails/login-username-ban.php:481
|
2821 |
#: app/module/ip-lockout/view/emails/report.php:515
|
2822 |
+
#: app/module/ip-lockout/view/locked.php:7
|
2823 |
msgid "WP Defender"
|
2824 |
msgstr ""
|
2825 |
|
2908 |
msgstr ""
|
2909 |
|
2910 |
#: app/module/ip-lockout/view/layouts/layout.php:21
|
2911 |
+
msgid "Total lockouts in the past 30 days"
|
2912 |
+
msgstr ""
|
2913 |
+
|
2914 |
+
#: app/module/ip-lockout/view/layouts/layout.php:34
|
2915 |
+
msgid "Login lockouts in the past 7 days"
|
2916 |
+
msgstr ""
|
2917 |
+
|
2918 |
+
#: app/module/ip-lockout/view/layouts/layout.php:40
|
2919 |
+
msgid "404 lockouts in the past 7 days"
|
2920 |
msgstr ""
|
2921 |
|
2922 |
#: app/module/ip-lockout/view/layouts/layout.php:54
|
2956 |
msgid "IP Blacklist"
|
2957 |
msgstr ""
|
2958 |
|
2959 |
+
#: app/module/ip-lockout/view/locked.php:74
|
2960 |
msgid "Powered by"
|
2961 |
msgstr ""
|
2962 |
|
3016 |
"these are common for bots to try logging in with. One username per line"
|
3017 |
msgstr ""
|
3018 |
|
3019 |
+
#: app/module/ip-lockout/view/migration.php:6
|
3020 |
+
msgid "Migration"
|
3021 |
+
msgstr ""
|
3022 |
+
|
3023 |
+
#: app/module/ip-lockout/view/migration.php:15
|
3024 |
+
msgid "Please hold on, we are updating your data, please don't close this tab..."
|
3025 |
+
msgstr ""
|
3026 |
+
|
3027 |
#: app/module/ip-lockout/view/notification/enabled.php:10
|
3028 |
msgid "Send email notifications"
|
3029 |
msgstr ""
|
3172 |
msgid "This WordPress core file appears modified"
|
3173 |
msgstr ""
|
3174 |
|
3175 |
+
#: app/module/scan/behavior/core-result.php:75
|
3176 |
+
#: app/module/scan/behavior/core-result.php:405
|
3177 |
+
#: app/module/scan/behavior/core-result.php:410
|
3178 |
+
#: app/module/scan/behavior/pro/content-result.php:206
|
3179 |
+
#: app/module/scan/behavior/pro/content-result.php:227
|
3180 |
+
#: app/module/scan/behavior/pro/content-result.php:232
|
3181 |
+
msgid "Defender doesn't have enough permission to remove this file"
|
3182 |
+
msgstr ""
|
3183 |
+
|
3184 |
+
#: app/module/scan/behavior/core-result.php:81
|
3185 |
msgid "This file can't not remove"
|
3186 |
msgstr ""
|
3187 |
|
3188 |
+
#: app/module/scan/behavior/core-result.php:101
|
3189 |
msgid "This file is not resolvable"
|
3190 |
msgstr ""
|
3191 |
|
3192 |
+
#: app/module/scan/behavior/core-result.php:105
|
3193 |
msgid ""
|
3194 |
"It seems the %s file is currently using by another process or isn't "
|
3195 |
"writeable."
|
3196 |
msgstr ""
|
3197 |
|
3198 |
+
#: app/module/scan/behavior/core-result.php:122
|
3199 |
+
#: app/module/scan/behavior/pro/content-result.php:56
|
3200 |
#: app/module/scan/behavior/pro/vuln-result.php:109
|
3201 |
msgid "Issue Details"
|
3202 |
msgstr ""
|
3203 |
|
3204 |
+
#: app/module/scan/behavior/core-result.php:132
|
3205 |
+
#: app/module/scan/behavior/pro/content-result.php:65
|
3206 |
msgid "Location"
|
3207 |
msgstr ""
|
3208 |
|
3209 |
+
#: app/module/scan/behavior/core-result.php:142
|
3210 |
msgid "Size"
|
3211 |
msgstr ""
|
3212 |
|
3213 |
+
#: app/module/scan/behavior/core-result.php:159
|
3214 |
+
#: app/module/scan/behavior/pro/content-result.php:73
|
3215 |
msgid "Date Added"
|
3216 |
msgstr ""
|
3217 |
|
3218 |
+
#: app/module/scan/behavior/core-result.php:197
|
3219 |
+
#: app/module/scan/behavior/pro/content-result.php:127
|
3220 |
msgid "Delete"
|
3221 |
msgstr ""
|
3222 |
|
3223 |
+
#: app/module/scan/behavior/core-result.php:199
|
3224 |
msgid ""
|
3225 |
"This will permanent remove the file/folder with all content, do you want to "
|
3226 |
"do this?"
|
3227 |
msgstr ""
|
3228 |
|
3229 |
+
#: app/module/scan/behavior/core-result.php:202
|
3230 |
+
#: app/module/scan/behavior/pro/content-result.php:132
|
3231 |
msgid "Yes"
|
3232 |
msgstr ""
|
3233 |
|
3234 |
+
#: app/module/scan/behavior/core-result.php:205
|
3235 |
+
#: app/module/scan/behavior/pro/content-result.php:135
|
3236 |
msgid "No"
|
3237 |
msgstr ""
|
3238 |
|
3239 |
+
#: app/module/scan/behavior/core-result.php:215
|
3240 |
msgid "Restore to Original"
|
3241 |
msgstr ""
|
3242 |
|
3243 |
+
#: app/module/scan/behavior/core-result.php:264
|
3244 |
msgid ""
|
3245 |
"A stray file has been found in your site directory, which your version of "
|
3246 |
"WordPress doesn't need. As far as we can tell, the file is harmless (and "
|
3249 |
"beforehand"
|
3250 |
msgstr ""
|
3251 |
|
3252 |
+
#: app/module/scan/behavior/core-result.php:280
|
3253 |
+
#: app/module/scan/behavior/core-result.php:302
|
3254 |
+
#: app/module/scan/behavior/core-result.php:324
|
3255 |
+
#: app/module/scan/behavior/pro/content-result.php:93
|
3256 |
msgid "Pulling source file..."
|
3257 |
msgstr ""
|
3258 |
|
3259 |
+
#: app/module/scan/behavior/core-result.php:297
|
3260 |
msgid ""
|
3261 |
"Compare your file with the original file in the WordPress repository. "
|
3262 |
"Pieces highlighted in red will be removed when you patch the file, and "
|
3263 |
"pieces highlighted in green will be added."
|
3264 |
msgstr ""
|
3265 |
|
3266 |
+
#: app/module/scan/behavior/core-result.php:319
|
3267 |
msgid ""
|
3268 |
"We found this folder in your WordPress file list. Your current version of "
|
3269 |
"WordPress doesn’t use this folder so it might belong to another "
|
3272 |
"support team for more information."
|
3273 |
msgstr ""
|
3274 |
|
3275 |
+
#: app/module/scan/behavior/pro/content-result.php:46
|
3276 |
msgid "Suspicious function found"
|
3277 |
msgstr ""
|
3278 |
|
3279 |
+
#: app/module/scan/behavior/pro/content-result.php:88
|
3280 |
msgid ""
|
3281 |
" There’s some suspicious looking code in the file %s. If you know the code "
|
3282 |
"is harmless you can ignore this warning. Otherwise, you can choose to "
|
3284 |
"recommend backing up your website."
|
3285 |
msgstr ""
|
3286 |
|
3287 |
+
#: app/module/scan/behavior/pro/content-result.php:113
|
3288 |
msgid ""
|
3289 |
"This will permanent delete the whole plugin containing this file, do you "
|
3290 |
"want to do this?"
|
3291 |
msgstr ""
|
3292 |
|
3293 |
+
#: app/module/scan/behavior/pro/content-result.php:116
|
3294 |
msgid ""
|
3295 |
"This will permanent delete the whole theme containing this file, do you "
|
3296 |
"want to do this?"
|
3297 |
msgstr ""
|
3298 |
|
3299 |
+
#: app/module/scan/behavior/pro/content-result.php:119
|
3300 |
msgid "This will permanent delete this file, do you want to do this?"
|
3301 |
msgstr ""
|
3302 |
|
3422 |
msgstr ""
|
3423 |
|
3424 |
#: app/module/scan/component/result-table.php:35
|
3425 |
+
#: app/module/scan/controller/main.php:807
|
3426 |
msgid "Issue"
|
3427 |
msgstr ""
|
3428 |
|
3483 |
msgid "Update Theme"
|
3484 |
msgstr ""
|
3485 |
|
3486 |
+
#: app/module/scan/controller/main.php:178
|
3487 |
+
#: app/module/scan/controller/main.php:439
|
3488 |
msgid "The suspicious file has been successfully ignored."
|
3489 |
msgid_plural "The suspicious files have been successfully ignored."
|
3490 |
msgstr[0] ""
|
3491 |
msgstr[1] ""
|
3492 |
|
3493 |
+
#: app/module/scan/controller/main.php:193
|
3494 |
+
#: app/module/scan/controller/main.php:410
|
3495 |
msgid "The suspicious file has been successfully restored."
|
3496 |
msgid_plural "The suspicious files have been successfully restored."
|
3497 |
msgstr[0] ""
|
3498 |
msgstr[1] ""
|
3499 |
|
3500 |
+
#: app/module/scan/controller/main.php:212
|
3501 |
msgid "The suspicious files has been successfully deleted."
|
3502 |
msgid_plural "The suspicious files have been successfully deleted."
|
3503 |
msgstr[0] ""
|
3504 |
msgstr[1] ""
|
3505 |
|
3506 |
+
#: app/module/scan/controller/main.php:218
|
3507 |
msgid "No item has been deleted"
|
3508 |
msgstr ""
|
3509 |
|
3510 |
+
#: app/module/scan/controller/main.php:235
|
3511 |
msgid "The suspicious files has been successfully resolved."
|
3512 |
msgid_plural "The suspicious files have been successfully resolved."
|
3513 |
msgstr[0] ""
|
3514 |
msgstr[1] ""
|
3515 |
|
3516 |
+
#: app/module/scan/controller/main.php:241
|
3517 |
msgid "No item has been resolved"
|
3518 |
msgstr ""
|
3519 |
|
3520 |
+
#: app/module/scan/controller/main.php:335
|
3521 |
msgid "This item has been resolved."
|
3522 |
msgstr ""
|
3523 |
|
3524 |
+
#: app/module/scan/controller/main.php:339
|
3525 |
msgid "Please try again!"
|
3526 |
msgstr ""
|
3527 |
|
3528 |
+
#: app/module/scan/controller/main.php:350
|
3529 |
+
#: app/module/scan/controller/main.php:386
|
3530 |
+
#: app/module/scan/controller/main.php:415
|
3531 |
+
#: app/module/scan/controller/main.php:444
|
3532 |
msgid "The item doesn't exist!"
|
3533 |
msgstr ""
|
3534 |
|
3535 |
+
#: app/module/scan/controller/main.php:380
|
3536 |
msgid "This item has been permanent removed."
|
3537 |
msgstr ""
|
3538 |
|
3539 |
+
#: app/module/scan/controller/main.php:519
|
3540 |
#: app/module/scan/view/layouts/layout.php:5
|
3541 |
#: app/module/scan/view/scanning.php:6 app/view/activator-free.php:13
|
3542 |
#: app/view/activator.php:13
|
3543 |
msgid "File Scanning"
|
3544 |
msgstr ""
|
3545 |
|
3546 |
+
#: app/module/scan/controller/main.php:530
|
3547 |
msgid "Scan In Progress"
|
3548 |
msgstr ""
|
3549 |
|
3550 |
+
#: app/module/scan/controller/main.php:531 app/module/scan/view/issues.php:37
|
3551 |
msgid ""
|
3552 |
"Your code is currently clean! There were no issues found during the last "
|
3553 |
"scan, though you can always perform a new scan anytime."
|
3554 |
msgstr ""
|
3555 |
|
3556 |
+
#: app/module/scan/controller/main.php:805
|
3557 |
msgid "File"
|
3558 |
msgstr ""
|
3559 |
|
3560 |
+
#: app/module/scan/controller/main.php:841
|
3561 |
msgid "Let’s get your site patched up."
|
3562 |
msgstr ""
|
3563 |
|
4039 |
"this email."
|
4040 |
msgstr ""
|
4041 |
|
4042 |
+
#: free/main-activator.php:60
|
4043 |
msgid "Get Members!"
|
4044 |
msgstr ""
|
4045 |
|
4046 |
+
#: free/main-activator.php:104
|
4047 |
msgid ""
|
4048 |
"%s, you now have access to Defender's pro features but you still have the "
|
4049 |
"free version installed. Let's upgrade Defender and unlock all those juicy "
|
4050 |
"features! %s"
|
4051 |
msgstr ""
|
4052 |
|
4053 |
+
#: free/main-activator.php:134
|
4054 |
msgid "<br/>Something went wrong. Please try again later!"
|
4055 |
msgstr ""
|
4056 |
|
4090 |
msgid "Rate %s"
|
4091 |
msgstr ""
|
4092 |
|
4093 |
+
#: main-activator.php:78
|
4094 |
msgid ""
|
4095 |
"We noticed you have both the free and pro versions of Defender installed, "
|
4096 |
"so we've automatically deactivated the free version for you."
|
4121 |
|
4122 |
#. Author URI of the plugin/theme
|
4123 |
msgid "http://premium.wpmudev.org/"
|
4124 |
+
msgstr ""
|
4125 |
+
|
4126 |
+
#: app/module/advanced-tools/view/login/otp.php:286
|
4127 |
+
#. translators: %s: site title
|
4128 |
+
msgctxt "site"
|
4129 |
+
msgid "← Back to %s"
|
4130 |
msgstr ""
|
main-activator.php
CHANGED
@@ -28,6 +28,12 @@ class WD_Main_Activator {
|
|
28 |
* Initial
|
29 |
*/
|
30 |
public function init() {
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( &$this, 'addSettingsLink' ) );
|
32 |
add_action( 'admin_enqueue_scripts', array( &$this, 'register_styles' ) );
|
33 |
if ( ! \WP_Defender\Behavior\Utils::instance()->checkRequirement() ) {
|
@@ -40,6 +46,7 @@ class WD_Main_Activator {
|
|
40 |
\Hammer\Base\Container::instance()->set( 'scan', new \WP_Defender\Module\Scan() );
|
41 |
\Hammer\Base\Container::instance()->set( 'audit', new \WP_Defender\Module\Audit() );
|
42 |
\Hammer\Base\Container::instance()->set( 'lockout', new \WP_Defender\Module\IP_Lockout() );
|
|
|
43 |
//no need to set debug
|
44 |
new \WP_Defender\Controller\Debug();
|
45 |
require_once $this->wp_defender->getPluginPath() . 'free-dashboard/module.php';
|
28 |
* Initial
|
29 |
*/
|
30 |
public function init() {
|
31 |
+
$db_ver = get_site_option( 'wd_db_version' );
|
32 |
+
if ( version_compare( $db_ver, '1.7', '<' ) ) {
|
33 |
+
add_site_option( 'defenderLockoutNeedUpdateLog', 1 );
|
34 |
+
\WP_Defender\Module\IP_Lockout\Component\Login_Protection_Api::createTables();
|
35 |
+
update_site_option( 'wd_db_version', "1.7" );
|
36 |
+
}
|
37 |
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( &$this, 'addSettingsLink' ) );
|
38 |
add_action( 'admin_enqueue_scripts', array( &$this, 'register_styles' ) );
|
39 |
if ( ! \WP_Defender\Behavior\Utils::instance()->checkRequirement() ) {
|
46 |
\Hammer\Base\Container::instance()->set( 'scan', new \WP_Defender\Module\Scan() );
|
47 |
\Hammer\Base\Container::instance()->set( 'audit', new \WP_Defender\Module\Audit() );
|
48 |
\Hammer\Base\Container::instance()->set( 'lockout', new \WP_Defender\Module\IP_Lockout() );
|
49 |
+
\Hammer\Base\Container::instance()->set( 'advanced_tool', new \WP_Defender\Module\Advanced_Tools() );
|
50 |
//no need to set debug
|
51 |
new \WP_Defender\Controller\Debug();
|
52 |
require_once $this->wp_defender->getPluginPath() . 'free-dashboard/module.php';
|
phpunit.xml
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
<phpunit
|
2 |
-
bootstrap="tests/bootstrap.php"
|
3 |
-
backupGlobals="false"
|
4 |
-
colors="true"
|
5 |
-
convertErrorsToExceptions="true"
|
6 |
-
convertNoticesToExceptions="true"
|
7 |
-
convertWarningsToExceptions="true"
|
8 |
-
>
|
9 |
-
<testsuites>
|
10 |
-
<testsuite>
|
11 |
-
<directory prefix="test-" suffix=".php">./tests/</directory>
|
12 |
-
</testsuite>
|
13 |
-
</testsuites>
|
14 |
-
</phpunit>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readme.txt
CHANGED
@@ -1,13 +1,13 @@
|
|
1 |
=== Defender Security, Monitoring, and Hack Protection ===
|
2 |
Plugin Name: Defender Security, Monitoring, and Hack Protection
|
3 |
-
Version: 1.
|
4 |
Author: WPMU DEV
|
5 |
Author URI: http://premium.wpmudev.org/
|
6 |
Contributors: WPMUDEV
|
7 |
Tags: Security, Security Tweaks, Hardening, IP lockout, Monitoring, Blacklist, Site Protection, Hacked, Security Scan
|
8 |
Requires at least: 3.5
|
9 |
Tested up to: 4.8
|
10 |
-
Stable tag: 1.
|
11 |
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
12 |
|
13 |
Protect WordPress from hackers with security tweaks, code scans, IP lockouts, and monitoring.
|
@@ -103,6 +103,14 @@ Hackers and bot attacks are not the only threat to your site. No matter what se
|
|
103 |
|
104 |
== Changelog ==
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
= 1.6.2 =
|
107 |
* New: CSV export for Audit Logging.
|
108 |
* Improvement: Email reports now have unsubscribe link, and link to Reports where email reports can be turned off.
|
1 |
=== Defender Security, Monitoring, and Hack Protection ===
|
2 |
Plugin Name: Defender Security, Monitoring, and Hack Protection
|
3 |
+
Version: 1.7
|
4 |
Author: WPMU DEV
|
5 |
Author URI: http://premium.wpmudev.org/
|
6 |
Contributors: WPMUDEV
|
7 |
Tags: Security, Security Tweaks, Hardening, IP lockout, Monitoring, Blacklist, Site Protection, Hacked, Security Scan
|
8 |
Requires at least: 3.5
|
9 |
Tested up to: 4.8
|
10 |
+
Stable tag: 1.7
|
11 |
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
12 |
|
13 |
Protect WordPress from hackers with security tweaks, code scans, IP lockouts, and monitoring.
|
103 |
|
104 |
== Changelog ==
|
105 |
|
106 |
+
= 1.7 =
|
107 |
+
* New: Now you can enable 2 factors authentication with Defender and Google Authenticator app, support for iOS and Android
|
108 |
+
* New: We can define how long the "Remember me" can take affect, via a new Security Tweak, called "Manage Login Duration"
|
109 |
+
* Improvement: IP Lockout logs now have separate tables, better for performance.
|
110 |
+
* Fix: Ignore a file in Scanning section sometimes coming back after couple of scans.
|
111 |
+
* Other minor enhancements/fixes
|
112 |
+
|
113 |
+
|
114 |
= 1.6.2 =
|
115 |
* New: CSV export for Audit Logging.
|
116 |
* Improvement: Email reports now have unsubscribe link, and link to Reports where email reports can be turned off.
|
uninstall.php
CHANGED
@@ -40,6 +40,7 @@ $cache->delete( 'cleanchecksum' );
|
|
40 |
\WP_Defender\Module\Scan\Model\Settings::instance()->delete();
|
41 |
\WP_Defender\Module\Hardener\Model\Settings::instance()->delete();
|
42 |
\WP_Defender\Module\IP_Lockout\Model\Settings::instance()->delete();
|
|
|
43 |
|
44 |
//clear old stuff
|
45 |
delete_site_option( 'wp_defender' );
|
40 |
\WP_Defender\Module\Scan\Model\Settings::instance()->delete();
|
41 |
\WP_Defender\Module\Hardener\Model\Settings::instance()->delete();
|
42 |
\WP_Defender\Module\IP_Lockout\Model\Settings::instance()->delete();
|
43 |
+
\WP_Defender\Module\Advanced_Tools\Model\Auth_Settings::instance()->delete();
|
44 |
|
45 |
//clear old stuff
|
46 |
delete_site_option( 'wp_defender' );
|
vendor/binary-to-text-php/Base2n.php
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Binary-to-text PHP Utilities
|
4 |
+
*
|
5 |
+
* @package binary-to-text-php
|
6 |
+
* @link https://github.com/ademarre/binary-to-text-php
|
7 |
+
* @author Andre DeMarre
|
8 |
+
* @copyright 2009-2013 Andre DeMarre
|
9 |
+
* @license http://opensource.org/licenses/MIT MIT
|
10 |
+
*/
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Class for binary-to-text encoding with a base of 2^n
|
14 |
+
*
|
15 |
+
* The Base2n class is for binary-to-text conversion. It employs a
|
16 |
+
* generalization of the algorithms used by many encoding schemes that
|
17 |
+
* use a fixed number of bits to encode each character. In other words,
|
18 |
+
* the base is a power of 2.
|
19 |
+
*
|
20 |
+
* Earlier versions of this class were named
|
21 |
+
* FixedBitNotation and FixedBitEncoding.
|
22 |
+
*
|
23 |
+
* @package binary-to-text-php
|
24 |
+
*/
|
25 |
+
class Base2n
|
26 |
+
{
|
27 |
+
protected $_chars;
|
28 |
+
protected $_bitsPerCharacter;
|
29 |
+
protected $_radix;
|
30 |
+
protected $_rightPadFinalBits;
|
31 |
+
protected $_padFinalGroup;
|
32 |
+
protected $_padCharacter;
|
33 |
+
protected $_caseSensitive;
|
34 |
+
protected $_charmap;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Constructor
|
38 |
+
*
|
39 |
+
* @param integer $bitsPerCharacter Bits to use for each encoded character
|
40 |
+
* @param string $chars Base character alphabet
|
41 |
+
* @param boolean $caseSensitive To decode in a case-sensitive manner
|
42 |
+
* @param boolean $rightPadFinalBits How to encode last character
|
43 |
+
* @param boolean $padFinalGroup Add padding to end of encoded output
|
44 |
+
* @param string $padCharacter Character to use for padding
|
45 |
+
*
|
46 |
+
* @throws InvalidArgumentException for incompatible parameters
|
47 |
+
*/
|
48 |
+
public function __construct(
|
49 |
+
$bitsPerCharacter,
|
50 |
+
$chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_',
|
51 |
+
$caseSensitive = TRUE, $rightPadFinalBits = FALSE,
|
52 |
+
$padFinalGroup = FALSE, $padCharacter = '=')
|
53 |
+
{
|
54 |
+
// Ensure validity of $chars
|
55 |
+
if (!is_string($chars) || ($charLength = strlen($chars)) < 2) {
|
56 |
+
throw new InvalidArgumentException('$chars must be a string of at least two characters');
|
57 |
+
}
|
58 |
+
|
59 |
+
// Ensure validity of $padCharacter
|
60 |
+
if ($padFinalGroup) {
|
61 |
+
if (!is_string($padCharacter) || !isset($padCharacter[0])) {
|
62 |
+
throw new InvalidArgumentException('$padCharacter must be a string of one character');
|
63 |
+
}
|
64 |
+
|
65 |
+
if ($caseSensitive) {
|
66 |
+
$padCharFound = strpos($chars, $padCharacter[0]);
|
67 |
+
} else {
|
68 |
+
$padCharFound = stripos($chars, $padCharacter[0]);
|
69 |
+
}
|
70 |
+
|
71 |
+
if ($padCharFound !== FALSE) {
|
72 |
+
throw new InvalidArgumentException('$padCharacter can not be a member of $chars');
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
// Ensure validity of $bitsPerCharacter
|
77 |
+
if (!is_int($bitsPerCharacter)) {
|
78 |
+
throw new InvalidArgumentException('$bitsPerCharacter must be an integer');
|
79 |
+
}
|
80 |
+
|
81 |
+
if ($bitsPerCharacter < 1) {
|
82 |
+
// $bitsPerCharacter must be at least 1
|
83 |
+
throw new InvalidArgumentException('$bitsPerCharacter can not be less than 1');
|
84 |
+
|
85 |
+
} elseif ($charLength < 1 << $bitsPerCharacter) {
|
86 |
+
// Character length of $chars is too small for $bitsPerCharacter
|
87 |
+
// Find greatest acceptable value of $bitsPerCharacter
|
88 |
+
$bitsPerCharacter = 1;
|
89 |
+
$radix = 2;
|
90 |
+
|
91 |
+
while ($charLength >= ($radix <<= 1) && $bitsPerCharacter < 8) {
|
92 |
+
$bitsPerCharacter++;
|
93 |
+
}
|
94 |
+
|
95 |
+
$radix >>= 1;
|
96 |
+
throw new InvalidArgumentException(
|
97 |
+
'$bitsPerCharacter can not be more than ' . $bitsPerCharacter
|
98 |
+
. ' given $chars length of ' . $charLength
|
99 |
+
. ' (max radix ' . $radix . ')');
|
100 |
+
|
101 |
+
} elseif ($bitsPerCharacter > 8) {
|
102 |
+
// $bitsPerCharacter must not be greater than 8
|
103 |
+
throw new InvalidArgumentException('$bitsPerCharacter can not be greater than 8');
|
104 |
+
|
105 |
+
} else {
|
106 |
+
$radix = 1 << $bitsPerCharacter;
|
107 |
+
}
|
108 |
+
|
109 |
+
$this->_chars = $chars;
|
110 |
+
$this->_bitsPerCharacter = $bitsPerCharacter;
|
111 |
+
$this->_radix = $radix;
|
112 |
+
$this->_rightPadFinalBits = $rightPadFinalBits;
|
113 |
+
$this->_padFinalGroup = $padFinalGroup;
|
114 |
+
$this->_padCharacter = $padCharacter[0];
|
115 |
+
$this->_caseSensitive = $caseSensitive;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Encode a string
|
120 |
+
*
|
121 |
+
* @param string $rawString Binary data to encode
|
122 |
+
* @return string
|
123 |
+
*/
|
124 |
+
public function encode($rawString)
|
125 |
+
{
|
126 |
+
// Unpack string into an array of bytes
|
127 |
+
$bytes = unpack('C*', $rawString);
|
128 |
+
$byteCount = count($bytes);
|
129 |
+
|
130 |
+
$encodedString = '';
|
131 |
+
$byte = array_shift($bytes);
|
132 |
+
$bitsRead = 0;
|
133 |
+
$oldBits = 0;
|
134 |
+
|
135 |
+
$chars = $this->_chars;
|
136 |
+
$bitsPerCharacter = $this->_bitsPerCharacter;
|
137 |
+
$rightPadFinalBits = $this->_rightPadFinalBits;
|
138 |
+
$padFinalGroup = $this->_padFinalGroup;
|
139 |
+
$padCharacter = $this->_padCharacter;
|
140 |
+
|
141 |
+
$charsPerByte = 8 / $bitsPerCharacter;
|
142 |
+
$encodedLength = $byteCount * $charsPerByte;
|
143 |
+
|
144 |
+
// Generate encoded output; each loop produces one encoded character
|
145 |
+
for ($c = 0; $c < $encodedLength; $c++) {
|
146 |
+
|
147 |
+
// Get the bits needed for this encoded character
|
148 |
+
if ($bitsRead + $bitsPerCharacter > 8) {
|
149 |
+
// Not enough bits remain in this byte for the current character
|
150 |
+
// Save the remaining bits before getting the next byte
|
151 |
+
$oldBitCount = 8 - $bitsRead;
|
152 |
+
$oldBits = $byte ^ ($byte >> $oldBitCount << $oldBitCount);
|
153 |
+
$newBitCount = $bitsPerCharacter - $oldBitCount;
|
154 |
+
|
155 |
+
if (!$bytes) {
|
156 |
+
// Last bits; match final character and exit loop
|
157 |
+
if ($rightPadFinalBits) $oldBits <<= $newBitCount;
|
158 |
+
$encodedString .= $chars[$oldBits];
|
159 |
+
|
160 |
+
if ($padFinalGroup) {
|
161 |
+
// Array of the lowest common multiples of $bitsPerCharacter and 8, divided by 8
|
162 |
+
$lcmMap = array(1 => 1, 2 => 1, 3 => 3, 4 => 1, 5 => 5, 6 => 3, 7 => 7, 8 => 1);
|
163 |
+
$bytesPerGroup = $lcmMap[$bitsPerCharacter];
|
164 |
+
$pads = $bytesPerGroup * $charsPerByte - ceil((strlen($rawString) % $bytesPerGroup) * $charsPerByte);
|
165 |
+
$encodedString .= str_repeat($padCharacter, $pads);
|
166 |
+
}
|
167 |
+
|
168 |
+
break;
|
169 |
+
}
|
170 |
+
|
171 |
+
// Get next byte
|
172 |
+
$byte = array_shift($bytes);
|
173 |
+
$bitsRead = 0;
|
174 |
+
|
175 |
+
} else {
|
176 |
+
$oldBitCount = 0;
|
177 |
+
$newBitCount = $bitsPerCharacter;
|
178 |
+
}
|
179 |
+
|
180 |
+
// Read only the needed bits from this byte
|
181 |
+
$bits = $byte >> 8 - ($bitsRead + ($newBitCount));
|
182 |
+
$bits ^= $bits >> $newBitCount << $newBitCount;
|
183 |
+
$bitsRead += $newBitCount;
|
184 |
+
|
185 |
+
if ($oldBitCount) {
|
186 |
+
// Bits come from seperate bytes, add $oldBits to $bits
|
187 |
+
$bits = ($oldBits << $newBitCount) | $bits;
|
188 |
+
}
|
189 |
+
|
190 |
+
$encodedString .= $chars[$bits];
|
191 |
+
}
|
192 |
+
|
193 |
+
return $encodedString;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Decode a string
|
198 |
+
*
|
199 |
+
* @param string $encodedString Data to decode
|
200 |
+
* @param boolean $strict Returns NULL if $encodedString contains an undecodable character
|
201 |
+
* @return string
|
202 |
+
*/
|
203 |
+
public function decode($encodedString, $strict = FALSE)
|
204 |
+
{
|
205 |
+
if (!$encodedString || !is_string($encodedString)) {
|
206 |
+
// Empty string, nothing to decode
|
207 |
+
return '';
|
208 |
+
}
|
209 |
+
|
210 |
+
$chars = $this->_chars;
|
211 |
+
$bitsPerCharacter = $this->_bitsPerCharacter;
|
212 |
+
$radix = $this->_radix;
|
213 |
+
$rightPadFinalBits = $this->_rightPadFinalBits;
|
214 |
+
$padFinalGroup = $this->_padFinalGroup;
|
215 |
+
$padCharacter = $this->_padCharacter;
|
216 |
+
$caseSensitive = $this->_caseSensitive;
|
217 |
+
|
218 |
+
// Get index of encoded characters
|
219 |
+
if ($this->_charmap) {
|
220 |
+
$charmap = $this->_charmap;
|
221 |
+
|
222 |
+
} else {
|
223 |
+
$charmap = array();
|
224 |
+
|
225 |
+
for ($i = 0; $i < $radix; $i++) {
|
226 |
+
$charmap[$chars[$i]] = $i;
|
227 |
+
}
|
228 |
+
|
229 |
+
$this->_charmap = $charmap;
|
230 |
+
}
|
231 |
+
|
232 |
+
// The last encoded character is $encodedString[$lastNotatedIndex]
|
233 |
+
$lastNotatedIndex = strlen($encodedString) - 1;
|
234 |
+
|
235 |
+
// Remove trailing padding characters
|
236 |
+
if ($padFinalGroup) {
|
237 |
+
while ($encodedString[$lastNotatedIndex] === $padCharacter) {
|
238 |
+
$encodedString = substr($encodedString, 0, $lastNotatedIndex);
|
239 |
+
$lastNotatedIndex--;
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
+
$rawString = '';
|
244 |
+
$byte = 0;
|
245 |
+
$bitsWritten = 0;
|
246 |
+
|
247 |
+
// Convert each encoded character to a series of unencoded bits
|
248 |
+
for ($c = 0; $c <= $lastNotatedIndex; $c++) {
|
249 |
+
|
250 |
+
if (!$caseSensitive && !isset($charmap[$encodedString[$c]])) {
|
251 |
+
// Encoded character was not found; try other case
|
252 |
+
if (isset($charmap[$cUpper = strtoupper($encodedString[$c])])) {
|
253 |
+
$charmap[$encodedString[$c]] = $charmap[$cUpper];
|
254 |
+
|
255 |
+
} elseif (isset($charmap[$cLower = strtolower($encodedString[$c])])) {
|
256 |
+
$charmap[$encodedString[$c]] = $charmap[$cLower];
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
if (isset($charmap[$encodedString[$c]])) {
|
261 |
+
$bitsNeeded = 8 - $bitsWritten;
|
262 |
+
$unusedBitCount = $bitsPerCharacter - $bitsNeeded;
|
263 |
+
|
264 |
+
// Get the new bits ready
|
265 |
+
if ($bitsNeeded > $bitsPerCharacter) {
|
266 |
+
// New bits aren't enough to complete a byte; shift them left into position
|
267 |
+
$newBits = $charmap[$encodedString[$c]] << $bitsNeeded - $bitsPerCharacter;
|
268 |
+
$bitsWritten += $bitsPerCharacter;
|
269 |
+
|
270 |
+
} elseif ($c !== $lastNotatedIndex || $rightPadFinalBits) {
|
271 |
+
// Zero or more too many bits to complete a byte; shift right
|
272 |
+
$newBits = $charmap[$encodedString[$c]] >> $unusedBitCount;
|
273 |
+
$bitsWritten = 8; //$bitsWritten += $bitsNeeded;
|
274 |
+
|
275 |
+
} else {
|
276 |
+
// Final bits don't need to be shifted
|
277 |
+
$newBits = $charmap[$encodedString[$c]];
|
278 |
+
$bitsWritten = 8;
|
279 |
+
}
|
280 |
+
|
281 |
+
$byte |= $newBits;
|
282 |
+
|
283 |
+
if ($bitsWritten === 8 || $c === $lastNotatedIndex) {
|
284 |
+
// Byte is ready to be written
|
285 |
+
$rawString .= pack('C', $byte);
|
286 |
+
|
287 |
+
if ($c !== $lastNotatedIndex) {
|
288 |
+
// Start the next byte
|
289 |
+
$bitsWritten = $unusedBitCount;
|
290 |
+
$byte = ($charmap[$encodedString[$c]] ^ ($newBits << $unusedBitCount)) << 8 - $bitsWritten;
|
291 |
+
}
|
292 |
+
}
|
293 |
+
|
294 |
+
} elseif ($strict) {
|
295 |
+
// Unable to decode character; abort
|
296 |
+
return NULL;
|
297 |
+
}
|
298 |
+
}
|
299 |
+
|
300 |
+
return $rawString;
|
301 |
+
}
|
302 |
+
}
|
vendor/binary-to-text-php/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
The MIT License (MIT)
|
2 |
+
|
3 |
+
Copyright (c) 2009-2013 Andre DeMarre
|
4 |
+
|
5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 |
+
of this software and associated documentation files (the "Software"), to deal
|
7 |
+
in the Software without restriction, including without limitation the rights
|
8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9 |
+
copies of the Software, and to permit persons to whom the Software is
|
10 |
+
furnished to do so, subject to the following conditions:
|
11 |
+
|
12 |
+
The above copyright notice and this permission notice shall be included in
|
13 |
+
all copies or substantial portions of the Software.
|
14 |
+
|
15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21 |
+
THE SOFTWARE.
|
vendor/binary-to-text-php/README.md
ADDED
@@ -0,0 +1,279 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Binary-to-Text Utilities for PHP
|
2 |
+
=================================
|
3 |
+
|
4 |
+
For now, the only class in this repository is **Base2n**.
|
5 |
+
|
6 |
+
Base2n is for binary-to-text conversion with arbitrary encoding schemes that represent binary data in a base 2<sup>n</sup> notation. It can handle non-standard variants of many standard encoding schemes such as [Base64][rfc4648base64] and [Base32][rfc4648base32]. Many binary-to-text encoding schemes use a fixed number of bits of binary data to generate each encoded character. Such schemes generalize to a single algorithm, implemented here.
|
7 |
+
|
8 |
+
[rfc4648base64]: http://tools.ietf.org/html/rfc4648#section-4 "RFC 4648 Base64 Specification"
|
9 |
+
[rfc4648base32]: http://tools.ietf.org/html/rfc4648#section-6 "RFC 4648 Base32 Specification"
|
10 |
+
|
11 |
+
Binary-to-text encoding is usually used to represent data in a notation that is safe for transport over text-based protocols, and there are several other practical uses. See the examples below.
|
12 |
+
|
13 |
+
|
14 |
+
|
15 |
+
Basic Base2n Usage
|
16 |
+
------------------
|
17 |
+
|
18 |
+
With Base2n, you define your encoding scheme parametrically. Let's instantiate a [Base32][rfc4648base32] encoder:
|
19 |
+
|
20 |
+
```php
|
21 |
+
// RFC 4648 base32 alphabet; case-insensitive
|
22 |
+
$base32 = new Base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
|
23 |
+
$encoded = $base32->encode('encode this');
|
24 |
+
// MVXGG33EMUQHI2DJOM======
|
25 |
+
```
|
26 |
+
|
27 |
+
|
28 |
+
### Constructor Parameters
|
29 |
+
|
30 |
+
- <code>integer $bitsPerCharacter</code> **Required**. The number of bits to use for each encoded character; 1–8. The most practical range is 1–6. The encoding's radix is a power of 2: <code>2^$bitsPerCharacter</code>.
|
31 |
+
1. [base-2, binary][binary]
|
32 |
+
2. [base-4, quaternary][quaternary]
|
33 |
+
3. [base-8, octal][octal]
|
34 |
+
4. [base-16, hexadecimal][hexadecimal]
|
35 |
+
5. [base-32][base32]
|
36 |
+
6. [base-64][base64]
|
37 |
+
7. base-128
|
38 |
+
8. base-256
|
39 |
+
|
40 |
+
[binary]: http://en.wikipedia.org/wiki/Binary_numeral_system "Binary Notation"
|
41 |
+
[quaternary]: http://en.wikipedia.org/wiki/Quaternary_numeral_system "Base-2 Notation"
|
42 |
+
[octal]: http://en.wikipedia.org/wiki/Octal "Octal Notation"
|
43 |
+
[hexadecimal]: http://en.wikipedia.org/wiki/Base16 "Hexadecimal Notation"
|
44 |
+
[base32]: http://en.wikipedia.org/wiki/Base32 "Base32 Encoding"
|
45 |
+
[base64]: http://en.wikipedia.org/wiki/Base64 "Base64 Encoding"
|
46 |
+
|
47 |
+
- <code>string $chars</code> This string specifies the base alphabet. Must be <code>2^$bitsPerCharacter</code> long. Default: <code>0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_</code>
|
48 |
+
|
49 |
+
- <code>boolean $caseSensitive</code> To decode in a case-sensitive manner. Default: <code>FALSE</code>
|
50 |
+
|
51 |
+
- <code>boolean $rightPadFinalBits</code> How to encode the last character when the bits remaining are fewer than <code>$bitsPerCharacter</code>. When <code>TRUE</code>, the bits to encode are placed in the most significant position of the final group of bits, with the lower bits set to <code>0</code>. When <code>FALSE</code>, the final bits are placed in the least significant position. For [RFC 4648][rfc4648] encodings, <code>$rightPadFinalBits</code>should be <code>TRUE</code>. Default: <code>FALSE</code>
|
52 |
+
|
53 |
+
[rfc4648]: http://tools.ietf.org/html/rfc4648 "RFC 4648: Base16, Base32, Base64"
|
54 |
+
|
55 |
+
- <code>boolean $padFinalGroup</code> It's common to encode characters in groups. For example, Base64 (which is based on 6 bits per character) converts 3 raw bytes into 4 encoded characters. If insufficient bytes remain at the end, the final group will be padded with <code>=</code> to complete a group of 4 characters, and the encoded length is always a multiple of 4. Although the information provided by the padding is redundant, some programs rely on it for decoding; Base2n does not. Default: <code>FALSE</code>
|
56 |
+
|
57 |
+
- <code>string $padCharacter</code> When <code>$padFinalGroup</code> is <code>TRUE</code>, this is the pad character used. Default: <code>=</code>
|
58 |
+
|
59 |
+
|
60 |
+
### <code>encode()</code> Parameters
|
61 |
+
|
62 |
+
- <code>string $rawString</code> **Required**. The data to be encoded.
|
63 |
+
|
64 |
+
|
65 |
+
### <code>decode()</code> Parameters
|
66 |
+
|
67 |
+
- <code>string $encodedString</code> **Required**. The string to be decoded.
|
68 |
+
- <code>boolean $strict</code> When <code>TRUE</code>, <code>NULL</code> will be returned if <code>$encodedString</code> contains an undecodable character. When <code>FALSE</code>, unknown characters are simply ignored. Default: <code>FALSE</code>
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
Examples
|
73 |
+
--------
|
74 |
+
|
75 |
+
PHP does not provide any Base32 encoding functions. By setting <code>$bitsPerCharacter</code> to 5 and specifying your desired alphabet in <code>$chars</code>, you can handle any variant of Base32:
|
76 |
+
|
77 |
+
```php
|
78 |
+
// RFC 4648 base32 alphabet; case-insensitive
|
79 |
+
$base32 = new Base2n(5, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', FALSE, TRUE, TRUE);
|
80 |
+
$encoded = $base32->encode('encode this');
|
81 |
+
// MVXGG33EMUQHI2DJOM======
|
82 |
+
```
|
83 |
+
|
84 |
+
```php
|
85 |
+
// RFC 4648 base32hex alphabet
|
86 |
+
$base32hex = new Base2n(5, '0123456789ABCDEFGHIJKLMNOPQRSTUV', FALSE, TRUE, TRUE);
|
87 |
+
$encoded = $base32hex->encode('encode this');
|
88 |
+
// CLN66RR4CKG78Q39EC======
|
89 |
+
```
|
90 |
+
|
91 |
+
|
92 |
+
Octal notation:
|
93 |
+
|
94 |
+
```php
|
95 |
+
$octal = new Base2n(3);
|
96 |
+
$encoded = $octal->encode('encode this');
|
97 |
+
// 312671433366214510072150322711
|
98 |
+
```
|
99 |
+
|
100 |
+
|
101 |
+
A convenient way to go back and forth between binary notation and its real binary representation:
|
102 |
+
|
103 |
+
```php
|
104 |
+
$binary = new Base2n(1);
|
105 |
+
$encoded = $binary->encode('encode this');
|
106 |
+
// 0110010101101110011000110110111101100100011001010010000001110100011010000110100101110011
|
107 |
+
$decoded = $binary->decode($encoded);
|
108 |
+
// encode this
|
109 |
+
```
|
110 |
+
|
111 |
+
|
112 |
+
PHP uses a proprietary binary-to-text encoding scheme to generate session identifiers from random hash digests. The most efficient way to store these session IDs in a database is to decode them back to their raw hash digests. PHP's encoding scheme is configured with the <code>[session.hash_bits_per_character][phphashbits]</code> php.ini setting. The decoded size depends on the hash function, set with <code>[session.hash_function][phphash]</code> in php.ini.
|
113 |
+
|
114 |
+
```php
|
115 |
+
// session.hash_function = 0
|
116 |
+
// session.hash_bits_per_character = 5
|
117 |
+
// 128-bit session ID
|
118 |
+
$sessionId = 'q3c8n4vqpq11i0vr6ucmafg1h3';
|
119 |
+
// Decodes to 16 bytes
|
120 |
+
$phpBase32 = new Base2n(5, '0123456789abcdefghijklmnopqrstuv');
|
121 |
+
$rawSessionId = $phpBase32->decode($sessionId);
|
122 |
+
```
|
123 |
+
|
124 |
+
```php
|
125 |
+
// session.hash_function = 1
|
126 |
+
// session.hash_bits_per_character = 6
|
127 |
+
// 160-bit session ID
|
128 |
+
$sessionId = '7Hf91mVc,q-9W1VndNNh3evVN83';
|
129 |
+
// Decodes to 20 bytes
|
130 |
+
$phpBase64 = new Base2n(6, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,');
|
131 |
+
$rawSessionId = $phpBase64->decode($sessionId);
|
132 |
+
```
|
133 |
+
|
134 |
+
[phphashbits]: http://php.net/manual/en/session.configuration.php#ini.session.hash-bits-per-character "PHP session.hash_bits_per_character"
|
135 |
+
[phphash]: http://php.net/manual/en/session.configuration.php#ini.session.hash-function "PHP session.hash_function"
|
136 |
+
|
137 |
+
|
138 |
+
Generate random security tokens:
|
139 |
+
```php
|
140 |
+
$tokenEncoder = new Base2n(6, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,');
|
141 |
+
$binaryToken = openssl_random_pseudo_bytes(32); // PHP >= 5.3
|
142 |
+
$token = $tokenEncoder->encode($binaryToken);
|
143 |
+
// Example: U6M132v9FG-AHhBVaQWOg1gjyUi1IogNxuen0i3u3ep
|
144 |
+
```
|
145 |
+
|
146 |
+
|
147 |
+
The rest of these examples are probably more fun than they are practical.
|
148 |
+
|
149 |
+
|
150 |
+
We can encode arbitrary data with a 7-bit encoding. (Note that this is not the same as the [7bit MIME content-transfer-encoding][7bit].)
|
151 |
+
```php
|
152 |
+
// This uses all 7-bit ASCII characters
|
153 |
+
$base128chars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
|
154 |
+
. "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
|
155 |
+
. "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F"
|
156 |
+
. "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
|
157 |
+
. "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F"
|
158 |
+
. "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F"
|
159 |
+
. "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F"
|
160 |
+
. "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x69\x7A\x7B\x7C\x7D\x7E\x7F";
|
161 |
+
|
162 |
+
$base128 = new Base2n(7, $base128chars);
|
163 |
+
$encoded = $base128->encode('encode this');
|
164 |
+
```
|
165 |
+
[7bit]: http://msdn.microsoft.com/en-us/library/ms526290(v=exchg.10).aspx "7bit MIME Content-Transfer-Encoding"
|
166 |
+
|
167 |
+
|
168 |
+
The following encoding guarantees that the most significant bit is set for every byte:
|
169 |
+
```php
|
170 |
+
// "High" base-128 encoding
|
171 |
+
$high128chars = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F"
|
172 |
+
. "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
|
173 |
+
. "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF"
|
174 |
+
. "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF"
|
175 |
+
. "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF"
|
176 |
+
. "\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF"
|
177 |
+
. "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF"
|
178 |
+
. "\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
|
179 |
+
|
180 |
+
$high128 = new Base2n(7, $high128chars);
|
181 |
+
$encoded = $high128->encode('encode this');
|
182 |
+
```
|
183 |
+
|
184 |
+
|
185 |
+
Let's create an encoding using exclusively non-printable control characters!
|
186 |
+
```php
|
187 |
+
// Base-32 non-printable character encoding
|
188 |
+
$noPrintChars = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
|
189 |
+
. "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
|
190 |
+
|
191 |
+
$nonPrintable32 = new Base2n(5, $noPrintChars);
|
192 |
+
$encoded = $nonPrintable32->encode('encode this');
|
193 |
+
```
|
194 |
+
|
195 |
+
|
196 |
+
Why not encode data using only whitespace? Here's a base-4 encoding using space, tab, new line, and carriage return:
|
197 |
+
```php
|
198 |
+
// Base-4 whitespace encoding
|
199 |
+
$whitespaceChars = " \t\n\r";
|
200 |
+
|
201 |
+
$whitespace = new Base2n(2, $whitespaceChars);
|
202 |
+
$encoded = $whitespace->encode('encode this');
|
203 |
+
// "\t\n\t\t\t\n\r\n\t\n \r\t\n\r\r\t\n\t \t\n\t\t \n \t\r\t \t\n\n \t\n\n\t\t\r \r"
|
204 |
+
|
205 |
+
$decoded = $whitespace->decode(
|
206 |
+
"\t\n\t\t\t\n\r\n\t\n \r\t\n\r\r\t\n\t \t\n\t\t \n \t\r\t \t\n\n \t\n\n\t\t\r \r"
|
207 |
+
);
|
208 |
+
// encode this
|
209 |
+
```
|
210 |
+
|
211 |
+
|
212 |
+
|
213 |
+
Counterexamples
|
214 |
+
----------------
|
215 |
+
|
216 |
+
Base2n is not slow, but it will never outperform an encoding function implemented in C. When one exists, use it instead.
|
217 |
+
|
218 |
+
|
219 |
+
PHP provides the <code>[base64_encode()][base64_encode]</code> and <code>[base64_decode()][base64_decode]</code> functions, and you should always use them for standard Base64. When you need to use a modified alphabet, you can translate the encoded output with <code>[strtr()][strtr]</code> or <code>[str_replace()][str_replace]</code>.
|
220 |
+
|
221 |
+
[base64_encode]: http://php.net/base64_encode "PHP base64_encode() Function"
|
222 |
+
[base64_decode]: http://php.net/base64_decode "PHP base64_decode() Function"
|
223 |
+
[strtr]: http://php.net/strtr "PHP strtr() Function"
|
224 |
+
[str_replace]: http://php.net/str_replace "PHP str_replace() Function"
|
225 |
+
|
226 |
+
A common variant of Base64 is [modified for URLs and filenames][rfc4648base64url], where <code>+</code> and <code>/</code> are replaced with <code>-</code> and <code>_</code>, and the <code>=</code> padding is omitted. It's better to handle this variant with native PHP functions:
|
227 |
+
|
228 |
+
```php
|
229 |
+
// RFC 4648 base64url with Base2n...
|
230 |
+
$base64url = new Base2n(6, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', TRUE, TRUE, FALSE);
|
231 |
+
$encoded = $base64url->encode("encode this \xBF\xC2\xBF");
|
232 |
+
// ZW5jb2RlIHRoaXMgv8K_
|
233 |
+
|
234 |
+
// RFC 4648 base64url with native functions...
|
235 |
+
$encoded = str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode("encode this \xBF\xC2\xBF"));
|
236 |
+
// ZW5jb2RlIHRoaXMgv8K_
|
237 |
+
```
|
238 |
+
|
239 |
+
[rfc4648base64url]: http://tools.ietf.org/html/rfc4648#page-7 "Modified Base64 for URLs"
|
240 |
+
|
241 |
+
|
242 |
+
Native functions get slightly more cumbersome when every position in the alphabet has changed, as seen in this example of [decoding a Bcrypt hash][bmcf]:
|
243 |
+
```php
|
244 |
+
// Decode the salt and digest from a Bcrypt hash
|
245 |
+
|
246 |
+
$hash = '$2y$14$i5btSOiulHhaPHPbgNUGdObga/GC.AVG/y5HHY1ra7L0C9dpCaw8u';
|
247 |
+
$encodedSalt = substr($hash, 7, 22);
|
248 |
+
$encodedDigest = substr($hash, 29, 31);
|
249 |
+
|
250 |
+
// Using Base2n...
|
251 |
+
$bcrypt64 = new Base2n(6, './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', TRUE, TRUE);
|
252 |
+
$rawSalt = $bcrypt64->decode($encodedSalt); // 16 bytes
|
253 |
+
$rawDigest = $bcrypt64->decode($encodedDigest); // 23 bytes
|
254 |
+
|
255 |
+
// Using native functions...
|
256 |
+
$bcrypt64alphabet = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
257 |
+
$base64alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
258 |
+
$rawSalt = base64_decode(strtr($encodedSalt, $bcrypt64alphabet, $base64alphabet)); // 16 bytes
|
259 |
+
$rawDigest = base64_decode(strtr($encodedDigest, $bcrypt64alphabet, $base64alphabet)); // 23 bytes
|
260 |
+
```
|
261 |
+
|
262 |
+
[bmcf]: https://github.com/ademarre/binary-mcf "Binary Modular Crypt Format (BMCF)"
|
263 |
+
|
264 |
+
You can encode and decode hexadecimal with <code>[bin2hex()][bin2hex]</code> and <code>[pack()][pack]</code>:
|
265 |
+
|
266 |
+
```php
|
267 |
+
// Hexadecimal with Base2n...
|
268 |
+
$hexadecimal = new Base2n(4);
|
269 |
+
$encoded = $hexadecimal->encode('encode this'); // 656e636f64652074686973
|
270 |
+
$decoded = $hexadecimal->decode($encoded); // encode this
|
271 |
+
|
272 |
+
// It's better to use native functions...
|
273 |
+
$encoded = bin2hex('encode this'); // 656e636f64652074686973
|
274 |
+
$decoded = pack('H*', $encoded); // encode this
|
275 |
+
// As of PHP 5.4 you can use hex2bin() instead of pack()
|
276 |
+
```
|
277 |
+
|
278 |
+
[bin2hex]: http://php.net/bin2hex "PHP bin2hex() Function"
|
279 |
+
[pack]: http://php.net/pack "PHP pack() Function"
|
vendor/binary-to-text-php/composer.json
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "ademarre/binary-to-text-php",
|
3 |
+
"description": "Collection of binary-to-text encoding utilities for PHP. Includes Base32 support and much more.",
|
4 |
+
"keywords": ["rfc4648", "base32", "octal", "base-8", "base-4", "binary"],
|
5 |
+
"type": "library",
|
6 |
+
"homepage": "https://github.com/ademarre/binary-to-text-php",
|
7 |
+
"license": "MIT",
|
8 |
+
"authors": [
|
9 |
+
{
|
10 |
+
"name": "Andre DeMarre",
|
11 |
+
"role": "Developer"
|
12 |
+
}
|
13 |
+
],
|
14 |
+
"require": {
|
15 |
+
"php": ">=5.2.14"
|
16 |
+
},
|
17 |
+
"autoload": {
|
18 |
+
"psr-0": { "Base2n": "" }
|
19 |
+
}
|
20 |
+
}
|
vendor/hammer/base/db-model.php
ADDED
@@ -0,0 +1,292 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Author: Hoang Ngo
|
4 |
+
*/
|
5 |
+
|
6 |
+
namespace Hammer\Base;
|
7 |
+
class DB_Model extends Model {
|
8 |
+
const EVENT_BEFORE_INSERT = 'beforeInsert', EVENT_AFTER_INSERT = 'afterInsert',
|
9 |
+
EVENT_BEFORE_UPDATE = 'beforeUpdate', EVENT_AFTER_UPDATE = 'afterUpdate',
|
10 |
+
EVENT_BEFORE_DELELTE = 'beforeDelete', EVENT_AFTER_DELETE = 'afterDelete';
|
11 |
+
|
12 |
+
public $id;
|
13 |
+
protected static $tableName = '';
|
14 |
+
|
15 |
+
public function save() {
|
16 |
+
if ( $this->id ) {
|
17 |
+
$this->update();
|
18 |
+
} else {
|
19 |
+
$this->insert();
|
20 |
+
}
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @return false|int|\WP_Error
|
25 |
+
*/
|
26 |
+
private function insert() {
|
27 |
+
if ( static::$tableName == null ) {
|
28 |
+
return new \WP_Error( 'db_error', 'No table specific' );
|
29 |
+
}
|
30 |
+
|
31 |
+
$this->trigger( self::EVENT_BEFORE_INSERT );
|
32 |
+
$data = $this->export();
|
33 |
+
if ( isset( $data['id'] ) && ! empty( $data['id'] ) ) {
|
34 |
+
return new \WP_Error( 'db_error', "This id already exists!" );
|
35 |
+
}
|
36 |
+
|
37 |
+
$id = self::getWPDB()->insert( self::getTable(), $data );
|
38 |
+
if ( $id == false ) {
|
39 |
+
error_log( self::getWPDB()->last_error );
|
40 |
+
|
41 |
+
return new \WP_Error( 'db_error', self::getWPDB()->last_error );
|
42 |
+
}
|
43 |
+
|
44 |
+
$this->trigger( self::EVENT_BEFORE_UPDATE );
|
45 |
+
|
46 |
+
return self::getWPDB()->insert_id;
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @return bool|\WP_Error
|
51 |
+
*/
|
52 |
+
private function update() {
|
53 |
+
if ( static::$tableName == null ) {
|
54 |
+
return new \WP_Error( 'db_error', 'No table specific' );
|
55 |
+
}
|
56 |
+
$this->trigger( self::EVENT_BEFORE_UPDATE );
|
57 |
+
$data = $this->export();
|
58 |
+
$check = self::findByID( $data['id'] );
|
59 |
+
if ( is_null( $check ) ) {
|
60 |
+
return new \WP_Error( 'db_error', "This record doesn't exists" );
|
61 |
+
}
|
62 |
+
unset( $data['id'] );
|
63 |
+
$affected = self::getWPDB()->update( self::getTable(), $data, array(
|
64 |
+
'id' => $check->id
|
65 |
+
) );
|
66 |
+
if ( $affected == false ) {
|
67 |
+
error_log( self::getWPDB()->last_error );
|
68 |
+
|
69 |
+
return new \WP_Error( 'db_error', self::getWPDB()->last_error );
|
70 |
+
}
|
71 |
+
$this->trigger( self::EVENT_AFTER_UPDATE );
|
72 |
+
|
73 |
+
return true;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @param $id
|
78 |
+
*
|
79 |
+
* @return mixed|null
|
80 |
+
*/
|
81 |
+
public static function findByID( $id ) {
|
82 |
+
if ( ! $id ) {
|
83 |
+
return null;
|
84 |
+
}
|
85 |
+
$sql = self::getWPDB()->prepare( "SELECT * FROM " . self::getTable() . " WHERE id = %d", $id );
|
86 |
+
$data = self::getWPDB()->get_row( $sql, ARRAY_A );
|
87 |
+
if ( is_array( $data ) && count( $data ) ) {
|
88 |
+
return self::bind( $data );
|
89 |
+
} else {
|
90 |
+
return null;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @param array $attributes
|
96 |
+
* @param null $orderBy
|
97 |
+
* @param string $order
|
98 |
+
*
|
99 |
+
* @return mixed|null
|
100 |
+
*/
|
101 |
+
public static function findOne( $attributes = array(), $orderBy = null, $order = 'ASC' ) {
|
102 |
+
$fields = self::buildFields();
|
103 |
+
$where = self::buildWhere( $attributes );
|
104 |
+
$sqlOrder = null;
|
105 |
+
if ( ! empty( $orderBy ) && in_array( $orderBy, $fields ) ) {
|
106 |
+
if ( ! in_array( strtolower( $order ), array( 'asc', 'desc' ) ) ) {
|
107 |
+
$order = 'ASC';
|
108 |
+
}
|
109 |
+
$sqlOrder = 'ORDER BY ' . $orderBy . ' ' . $order;
|
110 |
+
}
|
111 |
+
|
112 |
+
$sql = 'SELECT ' . implode( ', ', $fields ) . ' FROM ' . self::getTable() .
|
113 |
+
' WHERE ' . implode( 'AND', $where ) . $sqlOrder . ' LIMIT 0,1';
|
114 |
+
$data = self::getWPDB()->get_row( $sql, ARRAY_A );
|
115 |
+
if ( is_array( $data ) && count( $data ) ) {
|
116 |
+
return self::bind( $data );
|
117 |
+
}
|
118 |
+
|
119 |
+
return null;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @param array $attributes
|
124 |
+
* @param null $orderBy
|
125 |
+
* @param string $order
|
126 |
+
* @param null $limit
|
127 |
+
*
|
128 |
+
* @return array
|
129 |
+
*/
|
130 |
+
public static function findAll( $attributes = array(), $orderBy = null, $order = 'ASC', $limit = null ) {
|
131 |
+
$fields = self::buildFields();
|
132 |
+
$where = self::buildWhere( $attributes );
|
133 |
+
$sqlOrder = null;
|
134 |
+
if ( ! empty( $orderBy ) && in_array( $orderBy, $fields ) ) {
|
135 |
+
if ( ! in_array( strtolower( $order ), array( 'asc', 'desc' ) ) ) {
|
136 |
+
$order = 'ASC';
|
137 |
+
}
|
138 |
+
$sqlOrder = ' ORDER BY ' . $orderBy . ' ' . $order;
|
139 |
+
}
|
140 |
+
|
141 |
+
$sql = 'SELECT ' . implode( ', ', $fields ) . ' FROM ' . self::getTable() .
|
142 |
+
' WHERE ' . implode( ' AND ', $where ) . $sqlOrder;
|
143 |
+
if ( $limit ) {
|
144 |
+
$sql = $sql . ' LIMIT ' . $limit;
|
145 |
+
}
|
146 |
+
$data = self::getWPDB()->get_results( $sql, ARRAY_A );
|
147 |
+
$results = array();
|
148 |
+
if ( is_array( $data ) && count( $data ) ) {
|
149 |
+
foreach ( $data as $row ) {
|
150 |
+
$results[] = self::bind( $row );
|
151 |
+
}
|
152 |
+
}
|
153 |
+
|
154 |
+
return $results;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
*
|
159 |
+
*/
|
160 |
+
public function delete() {
|
161 |
+
global $wpdb;
|
162 |
+
$wpdb->delete( self::getTable(), array(
|
163 |
+
'id' => $this->id
|
164 |
+
) );
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @param array $attributes
|
169 |
+
* @param bool $limit
|
170 |
+
*
|
171 |
+
* @return int
|
172 |
+
*/
|
173 |
+
public static function deleteAll( $attributes = array(), $limit = false ) {
|
174 |
+
$where = self::buildWhere( $attributes );
|
175 |
+
$sql = "SELECT id from " . self::getTable() . " WHERE " . implode( ' AND ', $where );
|
176 |
+
if ( $limit != false ) {
|
177 |
+
$sql = $sql . ' LIMIT ' . $limit;
|
178 |
+
}
|
179 |
+
|
180 |
+
global $wpdb;
|
181 |
+
$ids = $wpdb->get_col( $sql );
|
182 |
+
if ( ! empty( $ids ) ) {
|
183 |
+
$sql = "DELETE from " . self::getTable() . " WHERE id";
|
184 |
+
$sql .= " IN (" . implode( ', ', array_fill( 0, count( $ids ), '%s' ) ) . ")";
|
185 |
+
$sql = call_user_func_array( array(
|
186 |
+
$wpdb,
|
187 |
+
'prepare'
|
188 |
+
), array_merge( array( $sql ), $ids ) );
|
189 |
+
$wpdb->query( $sql );
|
190 |
+
}
|
191 |
+
|
192 |
+
return count( $ids );
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* @param array $attributes
|
197 |
+
*
|
198 |
+
* @return null|string
|
199 |
+
*/
|
200 |
+
public static function count( $attributes = array() ) {
|
201 |
+
$where = self::buildWhere( $attributes );
|
202 |
+
$sql = "SELECT count(id) FROM " . self::getTable() . " WHERE " . implode( ' AND ', $where );
|
203 |
+
|
204 |
+
return self::getWPDB()->get_var( $sql );
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* @return \wpdb
|
209 |
+
*/
|
210 |
+
private static function getWPDB() {
|
211 |
+
global $wpdb;
|
212 |
+
|
213 |
+
return $wpdb;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* @param $data
|
218 |
+
*
|
219 |
+
* @return mixed
|
220 |
+
*/
|
221 |
+
private static function bind( $data ) {
|
222 |
+
$class = get_called_class();
|
223 |
+
$obj = new $class;
|
224 |
+
|
225 |
+
foreach ( $data as $key => $val ) {
|
226 |
+
$data[ $key ] = maybe_unserialize( $val );
|
227 |
+
}
|
228 |
+
|
229 |
+
$obj->import( $data );
|
230 |
+
|
231 |
+
return $obj;
|
232 |
+
}
|
233 |
+
|
234 |
+
private static function getTable() {
|
235 |
+
return self::getWPDB()->base_prefix . static::$tableName;
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* @return array
|
240 |
+
*/
|
241 |
+
private static function buildFields() {
|
242 |
+
$class = get_called_class();
|
243 |
+
$obj = new $class;
|
244 |
+
$data = $obj->export();
|
245 |
+
$fields = array_keys( $data );
|
246 |
+
|
247 |
+
return $fields;
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* @param array $attributes
|
252 |
+
*
|
253 |
+
* @return array
|
254 |
+
*/
|
255 |
+
private static function buildWhere( $attributes = array() ) {
|
256 |
+
if ( empty( $attributes ) ) {
|
257 |
+
return array( '1=1' );
|
258 |
+
}
|
259 |
+
$condition = array();
|
260 |
+
$fields = self::buildFields();
|
261 |
+
global $wpdb;
|
262 |
+
foreach ( $attributes as $key => $attribute ) {
|
263 |
+
if ( ! in_array( $key, $fields ) ) {
|
264 |
+
//this condition is not supported
|
265 |
+
continue;
|
266 |
+
}
|
267 |
+
if ( is_array( $attribute ) ) {
|
268 |
+
if ( isset( $attribute['compare'] ) ) {
|
269 |
+
$sql = $key . ' ' . $attribute['compare'] . ' %s';
|
270 |
+
$sql = $wpdb->prepare( $sql, $attribute['value'] );
|
271 |
+
$condition[] = $sql;
|
272 |
+
} elseif ( ! empty( $attribute ) ) {
|
273 |
+
$sql = $key . " IN (" . implode( ', ', array_fill( 0, count( $attribute ), '%s' ) ) . ")";
|
274 |
+
|
275 |
+
$sql = call_user_func_array( array(
|
276 |
+
$wpdb,
|
277 |
+
'prepare'
|
278 |
+
), array_merge( array( $sql ), $attribute ) );
|
279 |
+
$condition[] = $sql;
|
280 |
+
}
|
281 |
+
} elseif ( strpos( '%', $attribute ) === 0 ) {
|
282 |
+
$condition[] = $wpdb->prepare( $key . ' LIKE %s', $attribute );
|
283 |
+
} else {
|
284 |
+
$condition[] = $wpdb->prepare( $key . ' = %s', $attribute );
|
285 |
+
}
|
286 |
+
}
|
287 |
+
|
288 |
+
$condition = array_filter( $condition );
|
289 |
+
|
290 |
+
return $condition;
|
291 |
+
}
|
292 |
+
}
|
vendor/hammer/base/view.php
CHANGED
@@ -53,7 +53,6 @@ class View extends Component {
|
|
53 |
public function render( $view, $params = array() ) {
|
54 |
$this->trigger( self::EVENT_BEFORE_RENDER );
|
55 |
$view_file = $this->_base_path . DIRECTORY_SEPARATOR . $view . '.php';
|
56 |
-
|
57 |
if ( is_file( $view_file ) ) {
|
58 |
$content = $this->renderPHPFile( $view_file, $params );
|
59 |
$this->trigger( self::EVENT_AFTER_RENDER );
|
53 |
public function render( $view, $params = array() ) {
|
54 |
$this->trigger( self::EVENT_BEFORE_RENDER );
|
55 |
$view_file = $this->_base_path . DIRECTORY_SEPARATOR . $view . '.php';
|
|
|
56 |
if ( is_file( $view_file ) ) {
|
57 |
$content = $this->renderPHPFile( $view_file, $params );
|
58 |
$this->trigger( self::EVENT_AFTER_RENDER );
|
vendor/hammer/vendor/psr/log/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
vendor
|
|
vendor/hammer/vendor/wixel/gump/examples/basic_tags.php
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
$validator->validation_rules(array(
|
9 |
-
'comment' => 'required|max_len,500',
|
10 |
-
));
|
11 |
-
|
12 |
-
$validator->filter_rules(array(
|
13 |
-
'comment' => 'basic_tags',
|
14 |
-
));
|
15 |
-
|
16 |
-
// Valid Data
|
17 |
-
$_POST = array(
|
18 |
-
'comment' => '<strong>this is freaking awesome</strong><script>alert(1);</script>'
|
19 |
-
);
|
20 |
-
|
21 |
-
|
22 |
-
$_POST = $validator->run($_POST);
|
23 |
-
|
24 |
-
print_r($_POST);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/contains.php
DELETED
@@ -1,48 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
$rules = array(
|
9 |
-
'account_type' => "required|contains,pro free basic premium",
|
10 |
-
'priority' => "required|contains,'low' 'medium' 'very high'",
|
11 |
-
);
|
12 |
-
|
13 |
-
echo "\nVALID DATA TEST:\n\n";
|
14 |
-
|
15 |
-
// Valid Data
|
16 |
-
$_POST_VALID = array(
|
17 |
-
'account_type' => 'pro',
|
18 |
-
'priority' => 'very high'
|
19 |
-
);
|
20 |
-
|
21 |
-
$valid = $validator->validate(
|
22 |
-
$_POST_VALID, $rules
|
23 |
-
);
|
24 |
-
|
25 |
-
if($valid !== true) {
|
26 |
-
echo $validator->get_readable_errors(true);
|
27 |
-
} else {
|
28 |
-
echo "Validation passed! \n";
|
29 |
-
}
|
30 |
-
|
31 |
-
echo "\nINVALID DATA TEST:\n\n";
|
32 |
-
|
33 |
-
// Invalid
|
34 |
-
$_POST_INVALID = array(
|
35 |
-
'account_type' => 'bad',
|
36 |
-
'priority' => 'unknown'
|
37 |
-
);
|
38 |
-
|
39 |
-
$invalid = $validator->validate(
|
40 |
-
$_POST_INVALID, $rules
|
41 |
-
);
|
42 |
-
|
43 |
-
if($invalid !== true) {
|
44 |
-
echo $validator->get_readable_errors(true);
|
45 |
-
echo "\n\n";
|
46 |
-
} else {
|
47 |
-
echo "Validation passed!\n\n";
|
48 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/credit_card.php
DELETED
@@ -1,16 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
$_POST = array(
|
9 |
-
'cc' => '987230234-2498234-24234-23' // This is not a valid credit card number
|
10 |
-
);
|
11 |
-
|
12 |
-
$rules = array(
|
13 |
-
'cc' => 'valid_cc'
|
14 |
-
);
|
15 |
-
|
16 |
-
print_r($validator->validate($_POST, $rules));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/custom_validator.php
DELETED
@@ -1,44 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
// Add the custom validator
|
7 |
-
GUMP::add_validator("is_object", function($field, $input, $param = NULL) {
|
8 |
-
return is_object($input[$field]);
|
9 |
-
});
|
10 |
-
|
11 |
-
// Generic test data
|
12 |
-
$input_data = array(
|
13 |
-
'not_object' => "asdasd",
|
14 |
-
'valid_object' => new stdClass()
|
15 |
-
);
|
16 |
-
|
17 |
-
$rules = array(
|
18 |
-
'not_object' => "is_object",
|
19 |
-
'valid_object' => "is_object"
|
20 |
-
);
|
21 |
-
|
22 |
-
// METHOD 1 (Long):
|
23 |
-
|
24 |
-
$validator = new GUMP();
|
25 |
-
|
26 |
-
$validated = $validator->validate(
|
27 |
-
$input_data, $rules
|
28 |
-
);
|
29 |
-
|
30 |
-
if($validated === true) {
|
31 |
-
echo "Validation passed!";
|
32 |
-
} else {
|
33 |
-
echo $validator->get_readable_errors(true);
|
34 |
-
}
|
35 |
-
|
36 |
-
// METHOD 2 (Short):
|
37 |
-
|
38 |
-
$is_valid = GUMP::is_valid($input_data, $rules);
|
39 |
-
|
40 |
-
if($is_valid === true) {
|
41 |
-
echo "Validation passed!";
|
42 |
-
} else {
|
43 |
-
print_r($is_valid);
|
44 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/escaping_mysql_strings.php
DELETED
@@ -1,38 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
$_POST = array(
|
9 |
-
'username' => "my username",
|
10 |
-
'password' => "' OR ''='"
|
11 |
-
);
|
12 |
-
|
13 |
-
$validator->sanitize($_POST);
|
14 |
-
|
15 |
-
$filters = array(
|
16 |
-
'username' => 'noise_words',
|
17 |
-
'password' => 'trim|strtolower|addslashes'
|
18 |
-
);
|
19 |
-
|
20 |
-
print_r($validator->filter($_POST, $filters));
|
21 |
-
|
22 |
-
// OR (If you have a mysql connection)
|
23 |
-
|
24 |
-
$validator->sanitize($_POST);
|
25 |
-
|
26 |
-
$_POST = array(
|
27 |
-
'username' => "my username",
|
28 |
-
'password' => "' OR ''='"
|
29 |
-
);
|
30 |
-
|
31 |
-
$filters = array(
|
32 |
-
'username' => 'noise_words',
|
33 |
-
'password' => 'trim|strtolower'
|
34 |
-
);
|
35 |
-
|
36 |
-
$validator->filter($_POST, $filters);
|
37 |
-
|
38 |
-
echo mysql_real_escape_string($_POST['password']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/explicit_fields.php
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
error_reporting(-1);
|
5 |
-
|
6 |
-
ini_set('display_errors', 1);
|
7 |
-
|
8 |
-
require "../gump.class.php";
|
9 |
-
|
10 |
-
$data = array(
|
11 |
-
'str' => null
|
12 |
-
);
|
13 |
-
|
14 |
-
$rules = array(
|
15 |
-
'str' => 'required'
|
16 |
-
);
|
17 |
-
|
18 |
-
GUMP::set_field_name("str", "Street");
|
19 |
-
|
20 |
-
$validated = GUMP::is_valid($data, $rules);
|
21 |
-
|
22 |
-
if($validated === true) {
|
23 |
-
echo "Valid Street Address\n";
|
24 |
-
} else {
|
25 |
-
print_r($validated);
|
26 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/files.php
DELETED
@@ -1,41 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$_FILES = array(
|
7 |
-
'attachments' => array(
|
8 |
-
'name' => array("test1.png"),
|
9 |
-
'type' => array("image/png"),
|
10 |
-
'tmp_name' => array("/tmp/phpmFkEUe"),
|
11 |
-
'error' => array(0),
|
12 |
-
'size' => array(9855)
|
13 |
-
)
|
14 |
-
);
|
15 |
-
|
16 |
-
$errors = array();
|
17 |
-
|
18 |
-
$length = count($_FILES['attachments']['name']);
|
19 |
-
|
20 |
-
for($i = 0; $i < $length; $i++) {
|
21 |
-
$struct = array(
|
22 |
-
'name' => $_FILES['attachments']['name'][$i],
|
23 |
-
'type' => $_FILES['attachments']['type'][$i],
|
24 |
-
'tmp_name' => $_FILES['attachments']['tmp_name'][$i],
|
25 |
-
'error' => $_FILES['attachments']['error'][$i],
|
26 |
-
'size' => $_FILES['attachments']['size'][$i],
|
27 |
-
);
|
28 |
-
|
29 |
-
$validated = GUMP::is_valid($struct, array(
|
30 |
-
'name' => 'required',
|
31 |
-
'type' => 'required',
|
32 |
-
'tmp_name' => 'required',
|
33 |
-
'size' => 'required|numeric',
|
34 |
-
));
|
35 |
-
|
36 |
-
if($validated !== true) {
|
37 |
-
$errors[] = $validated;
|
38 |
-
}
|
39 |
-
}
|
40 |
-
|
41 |
-
print_r($errors);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/full_example.php
DELETED
@@ -1,62 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
// Set the data
|
9 |
-
|
10 |
-
$_POST = array(
|
11 |
-
'username' => 'SeanNieuwoudt',
|
12 |
-
'password' => 'mypassword',
|
13 |
-
'email' => 'sean@wixel.net',
|
14 |
-
'gender' => 'm',
|
15 |
-
'credit_card' => '9872389-2424-234224-234', // Obviously an invalid credit card number,
|
16 |
-
'bio' => 'This is good! I think I will switch to another language'
|
17 |
-
);
|
18 |
-
|
19 |
-
$_POST = $validator->sanitize($_POST); // You don't have to sanitize, but it's safest to do so.
|
20 |
-
|
21 |
-
// Let's define the rules and filters
|
22 |
-
|
23 |
-
$rules = array(
|
24 |
-
'username' => 'required|alpha_numeric|max_len,100|min_len,6',
|
25 |
-
'password' => 'required|max_len,100|min_len,6',
|
26 |
-
'email' => 'required|valid_email',
|
27 |
-
'gender' => 'required|exact_len,1',
|
28 |
-
'credit_card' => 'required|valid_cc',
|
29 |
-
'bio' => 'required'
|
30 |
-
);
|
31 |
-
|
32 |
-
$filters = array(
|
33 |
-
'username' => 'trim|sanitize_string',
|
34 |
-
'password' => 'trim|base64_encode',
|
35 |
-
'email' => 'trim|sanitize_email',
|
36 |
-
'gender' => 'trim'
|
37 |
-
);
|
38 |
-
|
39 |
-
$_POST = $validator->filter($_POST, $filters);
|
40 |
-
|
41 |
-
// You can run filter() or validate() first
|
42 |
-
|
43 |
-
$validated = $validator->validate(
|
44 |
-
$_POST, $rules
|
45 |
-
);
|
46 |
-
|
47 |
-
// Check if validation was successful
|
48 |
-
|
49 |
-
if($validated === TRUE)
|
50 |
-
{
|
51 |
-
echo "Successful Validation\n\n";
|
52 |
-
|
53 |
-
print_r($_POST); // You can now use POST data safely
|
54 |
-
|
55 |
-
exit;
|
56 |
-
}
|
57 |
-
else
|
58 |
-
{
|
59 |
-
print_r($_POST);
|
60 |
-
|
61 |
-
print_r($validated); // Shows all the rules that failed along with the data
|
62 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/guid.php
DELETED
@@ -1,18 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$data = array(
|
7 |
-
'guid' => "A98C5A1E-A742-4808-96FA-6F409E799937"
|
8 |
-
);
|
9 |
-
|
10 |
-
$is_valid = GUMP::is_valid($data, array(
|
11 |
-
'guid' => 'required|guidv4',
|
12 |
-
));
|
13 |
-
|
14 |
-
if($is_valid === true) {
|
15 |
-
// continue
|
16 |
-
} else {
|
17 |
-
print_r($is_valid);
|
18 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/handling_errors.php
DELETED
@@ -1,74 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
// Set the data
|
9 |
-
|
10 |
-
$_POST = array(
|
11 |
-
'username' => 'SeanNieuwoudt',
|
12 |
-
'password' => 'mypassword',
|
13 |
-
'email' => 'sean@wixel.net',
|
14 |
-
'gender' => 'm',
|
15 |
-
'credit_card' => '9872389-2424-234224-234', // Obviously an invalid credit card number,
|
16 |
-
'bio' => 'This is good! I think I will switch to another language'
|
17 |
-
);
|
18 |
-
|
19 |
-
$_POST = $validator->sanitize($_POST); // You don't have to sanitize, but it's safest to do so.
|
20 |
-
|
21 |
-
// Let's define the rules and filters
|
22 |
-
|
23 |
-
$rules = array(
|
24 |
-
'username' => 'required|alpha_numeric|max_len,100|min_len,40',
|
25 |
-
'password' => 'required|max_len,100|min_len,6',
|
26 |
-
'email' => 'required|valid_email',
|
27 |
-
'gender' => 'required|exact_len,1',
|
28 |
-
'credit_card' => 'required|valid_cc',
|
29 |
-
'bio' => 'required'
|
30 |
-
);
|
31 |
-
|
32 |
-
$filters = array(
|
33 |
-
'username' => 'trim|sanitize_string',
|
34 |
-
'password' => 'trim|base64_encode',
|
35 |
-
'email' => 'trim|sanitize_email',
|
36 |
-
'gender' => 'trim'
|
37 |
-
);
|
38 |
-
|
39 |
-
$_POST = $validator->filter($_POST, $filters);
|
40 |
-
|
41 |
-
// You can run filter() or validate() first
|
42 |
-
|
43 |
-
$validated = $validator->validate(
|
44 |
-
$_POST, $rules
|
45 |
-
);
|
46 |
-
|
47 |
-
if($validated === TRUE)
|
48 |
-
{
|
49 |
-
echo "Successful Validation\n\n";
|
50 |
-
|
51 |
-
print_r($_POST); // You can now use POST data safely
|
52 |
-
|
53 |
-
exit;
|
54 |
-
}
|
55 |
-
else
|
56 |
-
{
|
57 |
-
// You should know what form fields to expect, so you can reference them here for custom messages
|
58 |
-
echo "There were errors with the data you provided:\n";
|
59 |
-
|
60 |
-
foreach($validated as $v) {
|
61 |
-
switch($v['field']) {
|
62 |
-
case 'credit_card':
|
63 |
-
echo "- The credit card provided is not valid.\n";
|
64 |
-
break;
|
65 |
-
case 'username':
|
66 |
-
echo "- The username provided is not valid.\n";
|
67 |
-
break;
|
68 |
-
}
|
69 |
-
}
|
70 |
-
|
71 |
-
// Or you can simply use the built in helper to generate the error messages for you
|
72 |
-
// Passing a boolean true to is returns the errors as html, otherwise it returns an array
|
73 |
-
echo $validator->get_readable_errors(true);
|
74 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/match.php
DELETED
@@ -1,22 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$data = array(
|
7 |
-
'username' => "myusername",
|
8 |
-
'password' => "mypassword",
|
9 |
-
'password_confirm' => "mypa33word",
|
10 |
-
);
|
11 |
-
|
12 |
-
$is_valid = GUMP::is_valid($data, array(
|
13 |
-
'username' => 'required|alpha_numeric',
|
14 |
-
'password' => 'required|max_len,100|min_len,6',
|
15 |
-
'password_confirm' => 'equalsfield,password',
|
16 |
-
));
|
17 |
-
|
18 |
-
if($is_valid === true) {
|
19 |
-
// continue
|
20 |
-
} else {
|
21 |
-
print_r($is_valid);
|
22 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/noise_words.php
DELETED
@@ -1,18 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
// What are noise words? http://support.dtsearch.com/webhelp/dtsearch/noise_words.htm
|
9 |
-
|
10 |
-
$_POST = array(
|
11 |
-
'words' => "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English"
|
12 |
-
);
|
13 |
-
|
14 |
-
$filters = array(
|
15 |
-
'words' => 'noise_words'
|
16 |
-
);
|
17 |
-
|
18 |
-
print_r($validator->filter($_POST, $filters));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/sanitize_string.php
DELETED
@@ -1,16 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
$_POST = array(
|
9 |
-
'string' => '<script>alert(1); $("body").remove(); </script>'
|
10 |
-
);
|
11 |
-
|
12 |
-
$filters = array(
|
13 |
-
'string' => 'sanitize_string'
|
14 |
-
);
|
15 |
-
|
16 |
-
print_r($validator->filter($_POST, $filters));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/sanitize_whitelist.php
DELETED
@@ -1,45 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
require "../gump.class.php";
|
5 |
-
|
6 |
-
$validator = new GUMP();
|
7 |
-
|
8 |
-
$_POST = array(
|
9 |
-
'first_name' => 'Joe',
|
10 |
-
'last_name' => 'Black',
|
11 |
-
'nickname' => 'blackjoe', // unexpected field
|
12 |
-
);
|
13 |
-
|
14 |
-
$rules = array(
|
15 |
-
'first_name' => 'required|valid_name',
|
16 |
-
'last_name' => 'required|valid_name'
|
17 |
-
);
|
18 |
-
|
19 |
-
|
20 |
-
/**
|
21 |
-
* You can "whitelist" the submitted fileds: other fields will be ignored.
|
22 |
-
* Pass an array of fields as 2nd argument in 'sanitize' method, e.g.:
|
23 |
-
* $whitelist = array( 'first_name', 'last_name' );
|
24 |
-
*
|
25 |
-
* Tip: you can use the keys of rule/filter array as a whitelist
|
26 |
-
*/
|
27 |
-
$whitelist = array_keys($rules);
|
28 |
-
$_POST = $validator->sanitize( $_POST, $whitelist );
|
29 |
-
|
30 |
-
$validated = $validator->validate($_POST, $rules);
|
31 |
-
|
32 |
-
if( $validated === TRUE )
|
33 |
-
{
|
34 |
-
/**
|
35 |
-
* Now you are sure that the $_POST array contains only the fields
|
36 |
-
* included in whitelist.
|
37 |
-
*
|
38 |
-
* It's a good practice anyway, but it's very useful if you are
|
39 |
-
* using an ORM/active-records library to store data into database
|
40 |
-
* and you have to be sure that the fields match the table columns.
|
41 |
-
*
|
42 |
-
* E.g.: ... $db->table('products')->insert($_POST) ...
|
43 |
-
*/
|
44 |
-
print_r($_POST);
|
45 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/street_address.php
DELETED
@@ -1,22 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
error_reporting(-1);
|
5 |
-
|
6 |
-
ini_set('display_errors', 1);
|
7 |
-
|
8 |
-
require "../gump.class.php";
|
9 |
-
|
10 |
-
$data = array(
|
11 |
-
'street' => '6 Avondans Road'
|
12 |
-
);
|
13 |
-
|
14 |
-
$validated = GUMP::is_valid($data, array(
|
15 |
-
'street' => 'required|street_address'
|
16 |
-
));
|
17 |
-
|
18 |
-
if($validated === true) {
|
19 |
-
echo "Valid Street Address\n";
|
20 |
-
} else {
|
21 |
-
print_r($validated);
|
22 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/url_exists.php
DELETED
@@ -1,26 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
error_reporting(-1);
|
5 |
-
|
6 |
-
ini_set('display_errors', 1);
|
7 |
-
|
8 |
-
require "../gump.class.php";
|
9 |
-
|
10 |
-
$validator = new GUMP();
|
11 |
-
|
12 |
-
$_POST = array(
|
13 |
-
'url' => 'http://sudygausdjhasgdjasjhdasd987lkasjhdkasdkjs.com/' // This url obviously does not exist
|
14 |
-
);
|
15 |
-
|
16 |
-
$rules = array(
|
17 |
-
'url' => 'url_exists'
|
18 |
-
);
|
19 |
-
|
20 |
-
$is_valid = $validator->validate($_POST, $rules);
|
21 |
-
|
22 |
-
if($is_valid === true) {
|
23 |
-
echo "The URL provided is valid";
|
24 |
-
} else {
|
25 |
-
print_r($validator->get_readable_errors());
|
26 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/examples/utf-8.php
DELETED
@@ -1,24 +0,0 @@
|
|
1 |
-
#!/usr/bin/php -q
|
2 |
-
<?php
|
3 |
-
|
4 |
-
error_reporting(-1);
|
5 |
-
|
6 |
-
ini_set('display_errors', 1);
|
7 |
-
|
8 |
-
require "../gump.class.php";
|
9 |
-
|
10 |
-
$data = array(
|
11 |
-
'one' => 'Freiheit, Mobilität und Unabhängigkeit lebt. ö, Ä, é, or ß',
|
12 |
-
'two' => 'ß'
|
13 |
-
);
|
14 |
-
|
15 |
-
$validated = GUMP::is_valid($data, array(
|
16 |
-
'one' => 'required|min_len,10',
|
17 |
-
'two' => 'required|min_len,1',
|
18 |
-
));
|
19 |
-
|
20 |
-
if($validated === true) {
|
21 |
-
echo "Valid Text\n";
|
22 |
-
} else {
|
23 |
-
print_r($validated);
|
24 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/hammer/vendor/wixel/gump/gump.class.php
CHANGED
@@ -10,6 +10,7 @@
|
|
10 |
*
|
11 |
* @version 1.4
|
12 |
*/
|
|
|
13 |
class GUMP
|
14 |
{
|
15 |
//Singleton instance of GUMP
|
@@ -2129,3 +2130,4 @@ class GUMP
|
|
2129 |
}
|
2130 |
}
|
2131 |
} // EOC
|
|
10 |
*
|
11 |
* @version 1.4
|
12 |
*/
|
13 |
+
if (!class_exists('GUMP')) {
|
14 |
class GUMP
|
15 |
{
|
16 |
//Singleton instance of GUMP
|
2130 |
}
|
2131 |
}
|
2132 |
} // EOC
|
2133 |
+
}
|
vendor/hammer/wp/model.php
CHANGED
@@ -118,6 +118,37 @@ abstract class Model extends \Hammer\Base\Model {
|
|
118 |
$this->trigger( self::EVENT_AFTER_DELETE );
|
119 |
}
|
120 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
/**
|
122 |
*
|
123 |
* @param $id
|
@@ -208,14 +239,6 @@ abstract class Model extends \Hammer\Base\Model {
|
|
208 |
return $results;
|
209 |
}
|
210 |
|
211 |
-
private function cacheQuery() {
|
212 |
-
|
213 |
-
}
|
214 |
-
|
215 |
-
private function flushCacheQuery() {
|
216 |
-
|
217 |
-
}
|
218 |
-
|
219 |
/**
|
220 |
* @param array $attributes
|
221 |
*
|
@@ -330,6 +353,8 @@ abstract class Model extends \Hammer\Base\Model {
|
|
330 |
$i ++;
|
331 |
}
|
332 |
|
|
|
|
|
333 |
return $where;
|
334 |
}
|
335 |
|
@@ -342,10 +367,13 @@ abstract class Model extends \Hammer\Base\Model {
|
|
342 |
if ( isset( $value['compare'] ) ) {
|
343 |
$sql = 't' . $pos . '.' . $field . ' ' . $value['compare'] . ' %s';
|
344 |
$sql = $wpdb->prepare( $sql, $value['value'] );
|
345 |
-
}
|
346 |
$sql = 't' . $pos . "." . $field . " IN (" . implode( ', ', array_fill( 0, count( $value ), '%s' ) ) . ")";
|
347 |
|
348 |
$sql = call_user_func_array( array( $wpdb, 'prepare' ), array_merge( array( $sql ), $value ) );
|
|
|
|
|
|
|
349 |
}
|
350 |
|
351 |
return $sql;
|
118 |
$this->trigger( self::EVENT_AFTER_DELETE );
|
119 |
}
|
120 |
|
121 |
+
/**
|
122 |
+
* @param array $attributes
|
123 |
+
* @param null $orderBy
|
124 |
+
* @param null $order
|
125 |
+
* @param null $limit
|
126 |
+
*/
|
127 |
+
public static function deleteAll( $attributes = array(), $orderBy = null, $order = null, $limit = null ) {
|
128 |
+
if ( ! empty( $attributes ) ) {
|
129 |
+
$join = static::buildJoins();
|
130 |
+
} else {
|
131 |
+
$join = array();
|
132 |
+
}
|
133 |
+
$where = static::buildWhere( $attributes );
|
134 |
+
$sql = "SELECT ID FROM " . self::getWPDB()->posts . ' AS t0 ' . implode( ' ', $join ) . ' ' . implode( ' AND ', $where );
|
135 |
+
if ( ! empty( $orderBy ) && static::buildOrderBy( $orderBy ) != false ) {
|
136 |
+
$sql = $sql . ' ORDER BY ' . static::buildOrderBy( $orderBy );
|
137 |
+
if ( ! empty( $order ) && in_array( strtolower( $order ), array( 'desc', 'asc' ) ) ) {
|
138 |
+
$sql = $sql . ' ' . $order;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
if ( ! empty( $limit ) ) {
|
142 |
+
$sql .= ' LIMIT ' . $limit;
|
143 |
+
}
|
144 |
+
|
145 |
+
$ids = self::getWPDB()->get_col( $sql );
|
146 |
+
|
147 |
+
foreach ( $ids as $id ) {
|
148 |
+
wp_delete_post( $id );
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
/**
|
153 |
*
|
154 |
* @param $id
|
239 |
return $results;
|
240 |
}
|
241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
/**
|
243 |
* @param array $attributes
|
244 |
*
|
353 |
$i ++;
|
354 |
}
|
355 |
|
356 |
+
$where = array_filter( $where );
|
357 |
+
|
358 |
return $where;
|
359 |
}
|
360 |
|
367 |
if ( isset( $value['compare'] ) ) {
|
368 |
$sql = 't' . $pos . '.' . $field . ' ' . $value['compare'] . ' %s';
|
369 |
$sql = $wpdb->prepare( $sql, $value['value'] );
|
370 |
+
} elseif ( ! empty( $value ) ) {
|
371 |
$sql = 't' . $pos . "." . $field . " IN (" . implode( ', ', array_fill( 0, count( $value ), '%s' ) ) . ")";
|
372 |
|
373 |
$sql = call_user_func_array( array( $wpdb, 'prepare' ), array_merge( array( $sql ), $value ) );
|
374 |
+
} else {
|
375 |
+
//this case the in array is empty,
|
376 |
+
$sql = "";
|
377 |
}
|
378 |
|
379 |
return $sql;
|
vendor/hammer/wp/settings.php
CHANGED
@@ -17,7 +17,7 @@ use Hammer\Helper\Log_Helper;
|
|
17 |
class Settings extends Model {
|
18 |
private static $_instance;
|
19 |
|
20 |
-
const EVENT_BEFORE_SAVE = 'beforeSave', EVENT_AFTER_SAVE = 'afterSave';
|
21 |
/**
|
22 |
* Required, this will be the option name for storing
|
23 |
* @var string
|
@@ -59,7 +59,9 @@ class Settings extends Model {
|
|
59 |
}
|
60 |
|
61 |
public function delete() {
|
|
|
62 |
$ret = delete_option( $this->id );
|
63 |
$ret = delete_site_option( $this->id );
|
|
|
64 |
}
|
65 |
}
|
17 |
class Settings extends Model {
|
18 |
private static $_instance;
|
19 |
|
20 |
+
const EVENT_BEFORE_SAVE = 'beforeSave', EVENT_AFTER_SAVE = 'afterSave', EVENT_BEFORE_DELETE = 'beforeDelete', EVENT_AFTER_DELETED = 'afterDeleted';
|
21 |
/**
|
22 |
* Required, this will be the option name for storing
|
23 |
* @var string
|
59 |
}
|
60 |
|
61 |
public function delete() {
|
62 |
+
$this->trigger( self::EVENT_BEFORE_DELETE );
|
63 |
$ret = delete_option( $this->id );
|
64 |
$ret = delete_site_option( $this->id );
|
65 |
+
$this->trigger( self::EVENT_AFTER_DELETED );
|
66 |
}
|
67 |
}
|
wp-defender.php
CHANGED
@@ -1,9 +1,8 @@
|
|
1 |
<?php
|
2 |
-
|
3 |
/**
|
4 |
* Plugin Name: WP Defender
|
5 |
* Plugin URI: https://premium.wpmudev.org/project/wp-defender/
|
6 |
-
* Version: 1.
|
7 |
* Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
|
8 |
* Author: WPMU DEV
|
9 |
* Author URI: http://premium.wpmudev.org/
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* Plugin Name: WP Defender
|
4 |
* Plugin URI: https://premium.wpmudev.org/project/wp-defender/
|
5 |
+
* Version: 1.7
|
6 |
* Description: Get regular security scans, vulnerability reports, safety recommendations and customized hardening for your site in just a few clicks. Defender is the analyst and enforcer who never sleeps.
|
7 |
* Author: WPMU DEV
|
8 |
* Author URI: http://premium.wpmudev.org/
|